<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0,viewport-fit=cover"><title>若依框架 | SRS-Blog</title><meta name="author" content="SRS"><meta name="copyright" content="SRS"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="ffffff"><meta name="description" content="若依搭建若依版本官方若依官方针对不同开发需求提供了多个版本的框架，每个版本都有其独特的特点和适用场景：  前后端混合版本：RuoYi结合了SpringBoot和Bootstrap的前端开发框架，适合快速构建传统的Web应用程序，其中前端和后端代码在同一项目中协同工作。 前后端分离版本：RuoYi-Vue利用SpringBoot作为后端开发框架，与Vue.js结合，实现了前后端分离的开发模式。这种架">
<meta property="og:type" content="article">
<meta property="og:title" content="若依框架">
<meta property="og:url" content="https://srs-blog.github.io/2025/04/13/%E8%8B%A5%E4%BE%9D%E5%9F%BA%E7%A1%80%E5%BA%94%E7%94%A8%E7%AF%87/index.html">
<meta property="og:site_name" content="SRS-Blog">
<meta property="og:description" content="若依搭建若依版本官方若依官方针对不同开发需求提供了多个版本的框架，每个版本都有其独特的特点和适用场景：  前后端混合版本：RuoYi结合了SpringBoot和Bootstrap的前端开发框架，适合快速构建传统的Web应用程序，其中前端和后端代码在同一项目中协同工作。 前后端分离版本：RuoYi-Vue利用SpringBoot作为后端开发框架，与Vue.js结合，实现了前后端分离的开发模式。这种架">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://srs-blog.github.io/img/bac-1.jpg">
<meta property="article:published_time" content="2025-04-12T16:00:00.000Z">
<meta property="article:modified_time" content="2025-04-12T16:00:00.000Z">
<meta property="article:author" content="SRS">
<meta property="article:tag" content="博客">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://srs-blog.github.io/img/bac-1.jpg"><script type="application/ld+json">{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "headline": "若依框架",
  "url": "https://srs-blog.github.io/2025/04/13/%E8%8B%A5%E4%BE%9D%E5%9F%BA%E7%A1%80%E5%BA%94%E7%94%A8%E7%AF%87/",
  "image": "https://srs-blog.github.io/img/bac-1.jpg",
  "datePublished": "2025-04-12T16:00:00.000Z",
  "dateModified": "2025-04-12T16:00:00.000Z",
  "author": [
    {
      "@type": "Person",
      "name": "SRS",
      "url": "https://srs-blog.github.io/"
    }
  ]
}</script><link rel="shortcut icon" href="/img/klld.png"><link rel="canonical" href="https://srs-blog.github.io/2025/04/13/%E8%8B%A5%E4%BE%9D%E5%9F%BA%E7%A1%80%E5%BA%94%E7%94%A8%E7%AF%87/index.html"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.css" media="print" onload="this.media='all'"><script>
    (() => {
      
    const saveToLocal = {
      set: (key, value, ttl) => {
        if (!ttl) return
        const expiry = Date.now() + ttl * 86400000
        localStorage.setItem(key, JSON.stringify({ value, expiry }))
      },
      get: key => {
        const itemStr = localStorage.getItem(key)
        if (!itemStr) return undefined
        const { value, expiry } = JSON.parse(itemStr)
        if (Date.now() > expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return value
      }
    }

    window.btf = {
      saveToLocal,
      getScript: (url, attr = {}) => new Promise((resolve, reject) => {
        const script = document.createElement('script')
        script.src = url
        script.async = true
        Object.entries(attr).forEach(([key, val]) => script.setAttribute(key, val))
        script.onload = script.onreadystatechange = () => {
          if (!script.readyState || /loaded|complete/.test(script.readyState)) resolve()
        }
        script.onerror = reject
        document.head.appendChild(script)
      }),
      getCSS: (url, id) => new Promise((resolve, reject) => {
        const link = document.createElement('link')
        link.rel = 'stylesheet'
        link.href = url
        if (id) link.id = id
        link.onload = link.onreadystatechange = () => {
          if (!link.readyState || /loaded|complete/.test(link.readyState)) resolve()
        }
        link.onerror = reject
        document.head.appendChild(link)
      }),
      addGlobalFn: (key, fn, name = false, parent = window) => {
        if (!true && key.startsWith('pjax')) return
        const globalFn = parent.globalFn || {}
        globalFn[key] = globalFn[key] || {}
        globalFn[key][name || Object.keys(globalFn[key]).length] = fn
        parent.globalFn = globalFn
      }
    }
  
      
      const activateDarkMode = () => {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      const activateLightMode = () => {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', 'ffffff')
        }
      }

      btf.activateDarkMode = activateDarkMode
      btf.activateLightMode = activateLightMode

      const theme = saveToLocal.get('theme')
    
          const hour = new Date().getHours()
          const isNight = hour <= 6 || hour >= 18
          if (theme === undefined) isNight ? activateDarkMode() : activateLightMode()
          else theme === 'light' ? activateLightMode() : activateDarkMode()
        
      
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        document.documentElement.classList.toggle('hide-aside', asideStatus === 'hide')
      }
    
      
    const detectApple = () => {
      if (/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)) {
        document.documentElement.classList.add('apple')
      }
    }
    detectApple()
  
    })()
  </script><script>const GLOBAL_CONFIG = {
  root: '/',
  algolia: undefined,
  localSearch: {"path":"/search.xml","preload":false,"top_n_per_article":1,"unescape":false,"languages":{"hits_empty":"未找到符合您查询的内容：${query}","hits_stats":"共找到 ${hits} 篇文章"}},
  translate: {"defaultEncoding":2,"translateDelay":0,"msgToTraditionalChinese":"繁","msgToSimplifiedChinese":"简"},
  highlight: {"plugin":"highlight.js","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":230,"highlightFullpage":false,"highlightMacStyle":false},
  copy: {
    success: '复制成功',
    error: '复制失败',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: true,
    post: true
  },
  runtime: '',
  dateSuffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: undefined,
  lightbox: 'null',
  Snackbar: {"chs_to_cht":"已切换为繁体中文","cht_to_chs":"已切换为简体中文","day_to_night":"关灯啦🌙，当前已成功切换至夜间模式！","night_to_day":"开灯啦🌞，当前已成功切换至白天模式！","bgLight":"#49b1f5","bgDark":"#1f1f1f","position":"top-right"},
  infinitegrid: {
    js: 'https://cdn.jsdelivr.net/npm/@egjs/infinitegrid/dist/infinitegrid.min.js',
    buttonText: '加载更多'
  },
  isPhotoFigcaption: false,
  islazyloadPlugin: true,
  isAnchor: false,
  percent: {
    toc: true,
    rightside: false,
  },
  autoDarkmode: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: '若依框架',
  isHighlightShrink: false,
  isToc: true,
  pageType: 'post'
}</script><link rel="stylesheet" href="https://cdn1.tianli0.top/npm/element-ui@2.15.6/packages/theme-chalk/lib/index.css"><link rel="stylesheet" href="/css/custom.css"><link rel="stylesheet" href="/css/universe.css"><link rel="stylesheet" href="/css/emoji.css"><link rel="stylesheet" href="/css/progress_bar.css" media="defer" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/l-lin/font-awesome-animation/dist/font-awesome-animation.min.css"  media="defer" onload="this.media='all'"><link rel="stylesheet" href="/css/readPercent.css"><!-- hexo injector head_end start --><link rel="stylesheet" href="https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiper.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiperstyle.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://npm.elemecdn.com/hexo-butterfly-wowjs/lib/animate.min.css" media="print" onload="this.media='screen'"><link rel="stylesheet" href="https://npm.elemecdn.com/hexo-butterfly-tag-plugins-plus@latest/lib/assets/font-awesome-animation.min.css" media="defer" onload="this.media='all'"><link rel="stylesheet" href="https://npm.elemecdn.com/hexo-butterfly-tag-plugins-plus@latest/lib/tag_plugins.css" media="defer" onload="this.media='all'"><script src="https://npm.elemecdn.com/hexo-butterfly-tag-plugins-plus@latest/lib/assets/carousel-touch.js"></script><!-- hexo injector head_end end --><meta name="generator" content="Hexo 7.3.0"></head><body><div id="web_bg" style="background-image: url(/img/bac-5.png);"></div><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img text-center"><img src= "" data-lazy-src="/img/srs.jpg" onerror="this.onerror=null;this.src='/img/friend_404.gif'" alt="avatar"/></div><div class="site-data text-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">9</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">0</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">4</div></a></div><div class="menus_items"><div class="menus_item"><a class="site-page faa-parent animated-hover" href="/"><i class="fa-fw icon-home"></i><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-home"></use></svg><span> 首页</span></a></div><div class="menus_item"><a class="site-page faa-parent animated-hover" href="/archives/"><i class="fa-fw icon-shijianzhou"></i><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-shijianzhou"></use></svg><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page faa-parent animated-hover" href="/tags/"><i class="fa-fw icon-icon_pricetag"></i><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-icon_pricetag"></use></svg><span> 标签</span></a></div><div class="menus_item"><a class="site-page faa-parent animated-hover" href="/categories/"><i class="fa-fw icon-shoukuanfenlei"></i><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-shoukuanfenlei"></use></svg><span> 分类</span></a></div><div class="menus_item"><a class="site-page group faa-parent animated-hover hide" href="javascript:void(0);"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-liebiao"></use></svg><span> 休闲</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child faa-parent animated-hover" href="/bangumis/index.html"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-shoukuanfenlei">                   </use></svg><span> 追番</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/music/"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-yinle">                   </use></svg><span> 音乐</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/Gallery/"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-zhaopian1">                   </use></svg><span> 照片</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/game/"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-youxi">                   </use></svg><span> 游戏</span></a></li></ul></div><div class="menus_item"><a class="site-page faa-parent animated-hover" href="/comments/"><i class="fa-fw icon-liuyanban"></i><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-liuyanban"></use></svg><span> 留言板</span></a></div><div class="menus_item"><a class="site-page faa-parent animated-hover" href="/link/"><i class="fa-fw icon-youlian"></i><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-youlian"></use></svg><span> 友链</span></a></div><div class="menus_item"><a class="site-page faa-parent animated-hover" href="/about/"><i class="fa-fw icon-aixin"></i><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-aixin"></use></svg><span> 关于</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image: url(/img/bac-1.jpg);"><nav id="nav"><span id="blog-info"><a href="/" title="SRS-Blog"><span class="site-name">SRS-Blog</span></a></span><div id="menus"><div class="menus_items"><div class="menus_item"><a class="site-page faa-parent animated-hover" href="/"><i class="fa-fw icon-home"></i><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-home"></use></svg><span> 首页</span></a></div><div class="menus_item"><a class="site-page faa-parent animated-hover" href="/archives/"><i class="fa-fw icon-shijianzhou"></i><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-shijianzhou"></use></svg><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page faa-parent animated-hover" href="/tags/"><i class="fa-fw icon-icon_pricetag"></i><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-icon_pricetag"></use></svg><span> 标签</span></a></div><div class="menus_item"><a class="site-page faa-parent animated-hover" href="/categories/"><i class="fa-fw icon-shoukuanfenlei"></i><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-shoukuanfenlei"></use></svg><span> 分类</span></a></div><div class="menus_item"><a class="site-page group faa-parent animated-hover hide" href="javascript:void(0);"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-liebiao"></use></svg><span> 休闲</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child faa-parent animated-hover" href="/bangumis/index.html"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-shoukuanfenlei">                   </use></svg><span> 追番</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/music/"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-yinle">                   </use></svg><span> 音乐</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/Gallery/"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-zhaopian1">                   </use></svg><span> 照片</span></a></li><li><a class="site-page child faa-parent animated-hover" href="/game/"><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-youxi">                   </use></svg><span> 游戏</span></a></li></ul></div><div class="menus_item"><a class="site-page faa-parent animated-hover" href="/comments/"><i class="fa-fw icon-liuyanban"></i><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-liuyanban"></use></svg><span> 留言板</span></a></div><div class="menus_item"><a class="site-page faa-parent animated-hover" href="/link/"><i class="fa-fw icon-youlian"></i><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-youlian"></use></svg><span> 友链</span></a></div><div class="menus_item"><a class="site-page faa-parent animated-hover" href="/about/"><i class="fa-fw icon-aixin"></i><svg class="icon faa-tada" aria-hidden="true"><use xlink:href="#icon-aixin"></use></svg><span> 关于</span></a></div></div><center id="name-container"><a id="page-name" href="javascript:scrollToTop()">PAGE_NAME</a></center><div id="nav-right"><a class="sun_moon faa-parent animated-hover" οnclick="switchNightMode()" title="日间和夜间模式切换" id="nightmode-button"><svg class="faa-tada" style="height:25px;width:25px;fill:currentColor;position:relative;top:7px" viewBox="0 0 1024 1024"><use id="modeicon" xlink:href="#icon-weather-color_moon-stars">       </use></svg></a><div id="toggle-menu"><a><i class="fas fa-bars fa-fw"></i></a></div></div></div></nav><div id="post-info"><h1 class="post-title">若依框架</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2025-04-12T16:00:00.000Z" title="发表于 2025-04-13 00:00:00">2025-04-13</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2025-04-12T16:00:00.000Z" title="更新于 2025-04-13 00:00:00">2025-04-13</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/Java/">Java</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-wordcount"><i class="far fa-file-word fa-fw post-meta-icon"></i><span class="post-meta-label">总字数:</span><span class="word-count">11.1k</span><span class="post-meta-separator">|</span><i class="far fa-clock fa-fw post-meta-icon"></i><span class="post-meta-label">阅读时长:</span><span>47分钟</span></span><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title=""><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">浏览量:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span></div></div></div><section class="main-hero-waves-area waves-area"><svg class="waves-svg" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" viewBox="0 24 150 28" preserveAspectRatio="none" shape-rendering="auto"><defs><path id="gentle-wave" d="M -160 44 c 30 0 58 -18 88 -18 s 58 18 88 18 s 58 -18 88 -18 s 58 18 88 18 v 44 h -352 Z"></path></defs><g class="parallax"><use href="#gentle-wave" x="48" y="0"></use><use href="#gentle-wave" x="48" y="3"></use><use href="#gentle-wave" x="48" y="5"></use><use href="#gentle-wave" x="48" y="7"></use></g></svg></section><div id="post-top-cover"><img class="nolazyload" id="post-top-bg" src= "" data-lazy-src="background-image: url(/img/bac-1.jpg);"></div></header><main class="layout" id="content-inner"><div id="post"><article class="container post-content" id="article-container"><div id="post-outdate-notice" data="{&quot;limitDay&quot;:365,&quot;messagePrev&quot;:&quot;It has been&quot;,&quot;messageNext&quot;:&quot;days since the last update, the content of the article may be outdated.&quot;,&quot;postUpdate&quot;:&quot;2025-04-13 00:00:00&quot;}" hidden></div><h1 id="若依搭建"><a href="#若依搭建" class="headerlink" title="若依搭建"></a>若依搭建</h1><h2 id="若依版本"><a href="#若依版本" class="headerlink" title="若依版本"></a>若依版本</h2><h3 id="官方"><a href="#官方" class="headerlink" title="官方"></a>官方</h3><p>若依官方针对不同开发需求提供了多个版本的框架，每个版本都有其独特的特点和适用场景：</p>
<ul>
<li><strong>前后端混合版本</strong>：RuoYi结合了SpringBoot和Bootstrap的前端开发框架，适合快速构建传统的Web应用程序，其中前端和后端代码在同一项目中协同工作。</li>
<li><strong>前后端分离版本</strong>：RuoYi-Vue利用SpringBoot作为后端开发框架，与Vue.js结合，实现了前后端分离的开发模式。这种架构有助于提高开发效率，前后端可以独立开发和部署，更适合现代化的Web应用开发。</li>
<li><strong>微服务版本</strong>：RuoYi-Cloud基于Spring Cloud &amp; Alibaba微服务架构，为构建大型分布式系统提供了完整的解决方案。它支持服务发现、配置管理、负载均衡等微服务特性，适合需要高可扩展性和高可用性的企业级应用。</li>
<li><strong>移动端版本</strong>：RuoYi-App采用Uniapp进行开发，结合了Vue.js的优势，可以实现跨平台的移动端应用开发。一次编写，多端运行的能力使得它成为开发iOS和Android应用的理想选择。</li>
</ul>
<p><img src= "" data-lazy-src="/assets/image-20240406145452593.png" alt="image-20240406145452593"> </p>
<p>这些版本的框架为开发者提供了多样化的选择，无论是传统的Web应用、现代化的前后端分离应用，还是复杂的微服务架构和跨平台的移动端应用，都能找到合适的若依框架版本来满足开发需求。</p>
<h3 id="非官方"><a href="#非官方" class="headerlink" title="非官方"></a>非官方</h3><p>若依框架因其强大的功能和灵活性，吸引了众多第三方开发者基于其核心架构进行扩展和优化，从而形成了丰富的生态系统。</p>
<p>这些扩展不仅增强了若依框架的功能性，也满足了开发者在不同场景下的具体需求。例如：</p>
<ul>
<li>RuoYi-Vue3（前端升级Vue3 Element Plus Vite）<ul>
<li><a target="_blank" rel="noopener" href="https://github.com/yangzongzhuan/RuoYi-Vue3">https://github.com/yangzongzhuan/RuoYi-Vue3</a></li>
</ul>
</li>
<li>RuoYi-Vue-Plus（后端集成Mybatis-Plus、Hutool、OSS存储、分布式锁等组件）<ul>
<li><a target="_blank" rel="noopener" href="https://gitee.com/dromara/RuoYi-Vue-Plus">https://gitee.com/dromara/RuoYi-Vue-Plus</a></li>
</ul>
</li>
</ul>
<p><img src= "" data-lazy-src="/assets/image-20240407105246495.png" alt="image-20240407105246495"> </p>
<p>这些扩展版本的推出，使得若依框架能够更好地适应不同规模和类型的项目需求，从小型快速开发到大型企业级应用，都能提供相应的解决方案。开发者可以根据自己的具体需求选择合适的版本进行开发。</p>
<h2 id="RuoYi-Vue"><a href="#RuoYi-Vue" class="headerlink" title="RuoYi-Vue"></a>RuoYi-Vue</h2><p>lRuoYi-Vue版本，采用了前后端分离的单体架构设计：</p>
<p>软件环境：JDK、MySQL 、Redis 、Maven、Node</p>
<p>技术选型：Spring Boot、Spring Security、MyBatis、Jwt、Vue3、Element-Plus</p>
<p>官方地址：<a target="_blank" rel="noopener" href="https://gitee.com/y_project/RuoYi-Vue">https://gitee.com/y_project/RuoYi-Vue</a></p>
<p>扩展地址：<a target="_blank" rel="noopener" href="https://gitee.com/ys-gitee/RuoYi-Vue3">https://gitee.com/ys-gitee/RuoYi-Vue3</a></p>
<div class="table-container">
<table>
<thead>
<tr>
<th><strong>官方推荐</strong></th>
<th><strong>课程版本</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>JDK  &gt;= 1.8</td>
<td>JDK  11</td>
</tr>
<tr>
<td>Mysql  &gt;= 5.7.0</td>
<td>MySQL  8</td>
</tr>
<tr>
<td>Redis  &gt;= 3.0</td>
<td>Redis  5（Win）</td>
</tr>
<tr>
<td>Maven  &gt;= 3.0</td>
<td>Maven  3.6</td>
</tr>
<tr>
<td>Node  &gt;= 12</td>
<td>Node  16（Vue3）</td>
</tr>
</tbody>
</table>
</div>
<blockquote>
<p>为了确保教学活动的顺利进行，建议所有学生在开始前安装并配置好这些软件的版本。</p>
<p>如果学生在安装或配置过程中遇到问题，可以联系播妞获取帮助，播妞将提供详细的安装文档和安装包，</p>
</blockquote>
<h2 id="运行后端项目"><a href="#运行后端项目" class="headerlink" title="运行后端项目"></a>运行后端项目</h2><h3 id="初始化项目"><a href="#初始化项目" class="headerlink" title="初始化项目"></a>初始化项目</h3><h4 id="Git下载"><a href="#Git下载" class="headerlink" title="Git下载"></a>Git下载</h4><p>通过idea克隆若依源码，仓库地址：<a target="_blank" rel="noopener" href="https://gitee.com/y_project/RuoYi-Vue.git">https://gitee.com/y_project/RuoYi-Vue.git</a></p>
<p><img src= "" data-lazy-src="/assets/image-20240407113034379.png" alt="image-20240407113034379">   </p>
<h4 id="Maven构建"><a href="#Maven构建" class="headerlink" title="Maven构建"></a>Maven构建</h4><p>使用idea打开项目后，等待环境检查（主要是Maven下载项目依赖）</p>
<p><img src= "" data-lazy-src="/assets/image-20240407112841763.png" alt="image-20240407112841763"> </p>
<h3 id="MySQL相关"><a href="#MySQL相关" class="headerlink" title="MySQL相关"></a>MySQL相关</h3><h4 id="导入sql"><a href="#导入sql" class="headerlink" title="导入sql"></a>导入sql</h4><p>1、创建数据库<code>create schema ry-vue;</code></p>
<p>2、执行下图的sql脚本文件，完成导入</p>
<p><img src= "" data-lazy-src="/assets/image-20231115113710134.png" alt="image-20231115113710134"> </p>
<p>3、导入后<code>ry-vue</code>库内置30张表</p>
<p><img src= "" data-lazy-src="/assets/image-20231203211313383.png" alt="image-20231203211313383"> </p>
<h4 id="配置信息"><a href="#配置信息" class="headerlink" title="配置信息"></a>配置信息</h4><p>在<code>ruoyi-admin</code>模块下，编辑<code>resources</code>目录下的<code>application-druid.yml</code>，修改数据库连接</p>
<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 数据源配置</span></span><br><span class="line"><span class="attr">spring:</span></span><br><span class="line">    <span class="attr">datasource:</span></span><br><span class="line">        <span class="attr">type:</span> <span class="string">com.alibaba.druid.pool.DruidDataSource</span></span><br><span class="line">        <span class="attr">driverClassName:</span> <span class="string">com.mysql.cj.jdbc.Driver</span></span><br><span class="line">        <span class="attr">druid:</span></span><br><span class="line">            <span class="comment"># 主库数据源</span></span><br><span class="line">            <span class="attr">master:</span></span><br><span class="line">                <span class="attr">url:</span> <span class="string">数据库地址</span></span><br><span class="line">                <span class="attr">username:</span> <span class="string">数据库账号</span></span><br><span class="line">                <span class="attr">password:</span> <span class="string">数据库密码</span></span><br></pre></td></tr></table></figure>
<p><img src= "" data-lazy-src="/assets/image-20240407113858680.png" alt="image-20240407113858680"> </p>
<h3 id="Redis相关"><a href="#Redis相关" class="headerlink" title="Redis相关"></a>Redis相关</h3><h4 id="启动"><a href="#启动" class="headerlink" title="启动"></a>启动</h4><p>在redis解压目录下，执行<code>redis-server.exe redis.windows.conf</code>启动</p>
<p><img src= "" data-lazy-src="/assets/image-20240407114209508.png" alt="image-20240407114209508"> </p>
<h4 id="配置信息-1"><a href="#配置信息-1" class="headerlink" title="配置信息"></a>配置信息</h4><p>在<code>ruoyi-admin</code>模块下，<code>resources</code>目录下的<code>application.yml</code>，可以设置redis密码等相关信息</p>
<p><img src= "" data-lazy-src="/assets/image-20240407114421363.png" alt="image-20240407114421363"> </p>
<h3 id="项目运行"><a href="#项目运行" class="headerlink" title="项目运行"></a>项目运行</h3><p>在<code>ruoyi-admin</code>模块下，运行<code>com.ruoyi.RuoYiApplication.java</code>，出现如下图表示启动成功</p>
<p><img src= "" data-lazy-src="/assets/image-20231115114924549.png" alt="image-20231115114924549"> </p>
<p>后端运行成功可以通过([<a target="_blank" rel="noopener" href="http://localhost:8080">http://localhost:8080</a> )访问，但是不会出现静态页面，可以继续参考下面步骤部署前端，然后通过前端地址来访问。</p>
<p><img src= "" data-lazy-src="/assets/image-20240407115558123.png" alt="image-20240407115558123"> </p>
<h2 id="运行前端项目"><a href="#运行前端项目" class="headerlink" title="运行前端项目"></a>运行前端项目</h2><h3 id="初始化项目-1"><a href="#初始化项目-1" class="headerlink" title="初始化项目"></a>初始化项目</h3><p>进入开发目录下，使用vscode命令<code>code</code>打开项目</p>
  <figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">克隆vue3项目</span></span><br><span class="line">git clone https://gitee.com/ys-gitee/RuoYi-Vue3.git</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">通过vscode打开项目</span></span><br><span class="line">code ./RuoYi-Vue3</span><br></pre></td></tr></table></figure>
<h3 id="项目运行-1"><a href="#项目运行-1" class="headerlink" title="项目运行"></a>项目运行</h3><p>在vscode终端中输入以下命令：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">安装依赖</span></span><br><span class="line">npm install</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">建议不要直接使用 cnpm 安装依赖，会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题</span></span><br><span class="line">npm install --registry=https://registry.npmmirror.com</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">启动服务</span></span><br><span class="line">npm run dev</span><br></pre></td></tr></table></figure>
<p><img src= "" data-lazy-src="/assets/image-20240407134921686.png" alt="image-20240407134921686"> </p>
<p>打开浏览器，输入：([<a target="_blank" rel="noopener" href="http://localhost:80">http://localhost:80</a>) 默认账户/密码 <code>admin/admin123</code>）若能正确展示登录页面，并能成功登录，菜单及页面展示正常，则表明环境搭建成功</p>
<p><img src= "" data-lazy-src="/assets/image-20240407135003607.gif" alt="image-20240407135003607"> </p>
<h1 id="入门案例"><a href="#入门案例" class="headerlink" title="入门案例"></a>入门案例</h1><p>在若依项目成功搭建之后，深入了解其代码生成器功能是掌握框架的重要一环。</p>
<p>接下来，我们将利用若依框架的代码生成器实现CRM系统中的<strong>课程管理</strong>功能，这将使我们能够实际体验并掌握如何在项目中有效使用这一工具。</p>
<h2 id="功能需求"><a href="#功能需求" class="headerlink" title="功能需求"></a>功能需求</h2><blockquote>
<p>实现CRM系统中的课程管理功能，涵盖增加、删除、修改和查询课程信息的完整前后端代码。</p>
<p>原型地址：<a target="_blank" rel="noopener" href="https://app.mockplus.cn/run/prototype/_lwaPYSV9Ue6/byFT7QUzmCqJ/2AadzZnerRIDo?cps=collapse&amp;isShare=true">https://app.mockplus.cn/run/prototype/_lwaPYSV9Ue6/byFT7QUzmCqJ/2AadzZnerRIDo?cps=collapse&amp;isShare=true</a></p>
</blockquote>
<p><img src= "" data-lazy-src="/assets/image-20240407145252756.png" alt="image-20240407145252756"> </p>
<h2 id="步骤分析"><a href="#步骤分析" class="headerlink" title="步骤分析"></a>步骤分析</h2><p>1、准备课程表结构和数据sql文件，导入到数据库中</p>
<p>2、登录系统（系统工具 -&gt; 代码生成 -&gt; 导入课程表）</p>
<p>3、代码生成列表中找到课程表（可预览、编辑、同步、删除生成配置）</p>
<p>4、点击生成代码会得到一个<code>ruoyi.zip</code></p>
<p>5、执行sql文件导入菜单，按照包内目录结构复制到自己的项目中即可</p>
<h2 id="代码生成"><a href="#代码生成" class="headerlink" title="代码生成"></a>代码生成</h2><h3 id="提供课程表"><a href="#提供课程表" class="headerlink" title="提供课程表"></a>提供课程表</h3><p>准备课程表结构和数据sql文件，导入到数据库中</p>
<p> <img src= "" data-lazy-src="/assets/image-20240407160249913.png" alt="image-20240407145252756"></p>
<h3 id="系统导入"><a href="#系统导入" class="headerlink" title="系统导入"></a>系统导入</h3><p>登录系统（系统工具 -&gt; 代码生成 -&gt; 导入课程表）</p>
<p><img src= "" data-lazy-src="/assets/image-20240407145252756.gif" alt="image-20240407145252756"> </p>
<h3 id="配置代码"><a href="#配置代码" class="headerlink" title="配置代码"></a>配置代码</h3><p>代码生成列表中找到课程表（可预览、编辑、同步、删除生成配置）</p>
<p><img src= "" data-lazy-src="/assets/image-20240515194239631.png" alt="image-20240515194239631" style="zoom:100%;" />    </p>
<h3 id="点击生成"><a href="#点击生成" class="headerlink" title="点击生成"></a>点击生成</h3><p>点击生成代码，得到一个<code>ruoyi.zip</code></p>
<p><img src= "" data-lazy-src="/assets/image-20240407171714267.png" alt="image-20240407171714267" style="zoom:65%;" />   </p>
<p>解压后得到：后端代码、前端代码、菜单sql</p>
<p><img src= "" data-lazy-src="/assets/image-20240407171214375.png" alt="image-20240407171214375" style="zoom:80%;" />  </p>
<h2 id="代码导入"><a href="#代码导入" class="headerlink" title="代码导入"></a>代码导入</h2><h3 id="导入课程菜单"><a href="#导入课程菜单" class="headerlink" title="导入课程菜单"></a>导入课程菜单</h3><p>执行sql脚本，导入菜单数据</p>
<p><img src= "" data-lazy-src="/assets/image-20240407172732924.png" alt="image-20240407172732924"> </p>
<h3 id="导入后端代码"><a href="#导入后端代码" class="headerlink" title="导入后端代码"></a>导入后端代码</h3><p>将生成的后端代码和mappep文件，导入<code>ruoyi-admin</code>模块中 </p>
<p><img src= "" data-lazy-src="/assets/image-20240515194048039.png" alt="image-20240515194048039"> </p>
<blockquote>
<p>注意：如果导入后的代码重启后没生效，可以通过maven先clean再启动</p>
</blockquote>
<h3 id="导入前端代码"><a href="#导入前端代码" class="headerlink" title="导入前端代码"></a>导入前端代码</h3><p>将生成的前端代码，导入<code>ruoyi-ui</code>模块中</p>
<p><img src= "" data-lazy-src="/assets/image-20240515194033701.png" alt="image-20240515194033701">   </p>
<h2 id="访问测试"><a href="#访问测试" class="headerlink" title="访问测试"></a>访问测试</h2><p>代码生成器默认生成的<strong>课程管理</strong>模块在<strong>系统工具</strong>菜单下，打开测试CRUD功能</p>
<p><img src= "" data-lazy-src="/assets/image-20240515194309391.png" alt="image-20240515194309391">   </p>
<h1 id="功能详解"><a href="#功能详解" class="headerlink" title="功能详解"></a>功能详解</h1><p>我们将对若依的通用功能进行详解。本章内容分为三个重点部分：</p>
<h2 id="系统管理"><a href="#系统管理" class="headerlink" title="系统管理"></a>系统管理</h2><h3 id="权限系统"><a href="#权限系统" class="headerlink" title="权限系统"></a>权限系统</h3><h4 id="演示"><a href="#演示" class="headerlink" title="演示"></a>演示</h4><p>若依提供了企业级通用权限系统，我们这里拿CRM系统先给大家演示下：</p>
<p>地址：<a target="_blank" rel="noopener" href="https://huike-crm.itheima.net/">https://huike-crm.itheima.net/</a></p>
<ul>
<li><p>demo账号（超级管理员），可以查看所有功能菜单</p>
</li>
<li><p>zhangsan账号（市场专员），可以查看线索管理菜单</p>
</li>
<li><p>yueyue账号（销售专员），可以查看商机、合同等菜单</p>
</li>
</ul>
<p><img src= "" data-lazy-src="/assets/image-20240515194350937.png" alt="image-20240515194350937"> </p>
<h4 id="RBAC"><a href="#RBAC" class="headerlink" title="RBAC"></a>RBAC</h4><p>lRBAC（基于角色的访问控制）是一种广泛使用的访问控制模型，通过角色来分配和管理用户的菜单权限。</p>
<p><img src= "" data-lazy-src="/assets/image-20240515194432239.png" alt="image-20240515194432239"> </p>
<h4 id="表关系"><a href="#表关系" class="headerlink" title="表关系"></a>表关系</h4><p><img src= "" data-lazy-src="/assets/image-20240515194525518.png" alt="image-20240515194525518"> </p>
<p><img src= "" data-lazy-src="/assets/image-20240515194550233.png" alt="image-20240515194550233"> </p>
<h4 id="案例"><a href="#案例" class="headerlink" title="案例"></a>案例</h4><p>创建新用户小智并关联课研人员角色，仅限课程管理和统计分析菜单访问。</p>
<p><img src= "" data-lazy-src="/assets/image-20240515211530662.png" alt="image-20240515211530662"> </p>
<p>实现步骤：</p>
<p>①创建菜单</p>
<p>②创建角色，并分配权限</p>
<p>③创建用户，并关联角色</p>
<p><img src= "" data-lazy-src="/assets/image-20240515194805143.png" alt="image-20240515194805143"> </p>
<h3 id="数据字典"><a href="#数据字典" class="headerlink" title="数据字典"></a>数据字典</h3><h4 id="介绍"><a href="#介绍" class="headerlink" title="介绍"></a>介绍</h4><p>若依内置的数据字典，用于维护系统中常见的静态数据。例如：性别、状态…</p>
<p><img src= "" data-lazy-src="/assets/image-20240515194849692.png" alt="image-20240515194849692"> </p>
<p>功能包括：字典类型管理、字典数据管理</p>
<p> <img src= "" data-lazy-src="/assets/image-20240515194953367.png" alt="image-20240515194953367"> </p>
<h4 id="表关系-1"><a href="#表关系-1" class="headerlink" title="表关系"></a>表关系</h4><p><img src= "" data-lazy-src="/assets/image-20240515195031748.png" alt="image-20240515195031748"> </p>
<h4 id="案例-1"><a href="#案例-1" class="headerlink" title="案例"></a>案例</h4><p>将课程管理的学科字段改为数据字典维护。</p>
<p><img src= "" data-lazy-src="/assets/image-20240515211609621.png" alt="image-20240515211609621"> </p>
<p>实现步骤：</p>
<p>①添加字典类型和数据</p>
<p><img src= "" data-lazy-src="/assets/image-20240515195114801.png" alt="image-20240515195114801"> </p>
<p>②修改代码生成信息</p>
<p><img src= "" data-lazy-src="/assets/image-20240515195134472.png" alt="image-20240515195134472"> </p>
<p>③下载代码，导入前端</p>
<p><img src= "" data-lazy-src="/assets/image-20240515195146589.png" alt="image-20240515195146589"> </p>
<h3 id="参数设置"><a href="#参数设置" class="headerlink" title="参数设置"></a>参数设置</h3><p>参数设置：对系统中的参数进行动态维护。</p>
<p><img src= "" data-lazy-src="/assets/image-20240515195404229.png" alt="image-20240515195404229"> </p>
<p>关闭登录验证码</p>
<p><img src= "" data-lazy-src="/assets/image-20240515195419521.png" alt="image-20240515195419521"></p>
<h3 id="通知公告"><a href="#通知公告" class="headerlink" title="通知公告"></a>通知公告</h3><p>RuoYi的通知公告功能提供了一个方便的方式来发布和管理通知、公告和新闻等信息。管理员可以创建、编辑和删除通知（支持富文本编辑和附件上传）。</p>
<p>系统将信息发送给指定的用户、部门或角色。用户可以通过系统界面或电子邮件接收通知，从而确保信息及时传达（这部分需要自己开发）。</p>
<p>通知公告功能有助于组织内部沟通和信息传递，提高了工作效率和信息共享。</p>
<p><img src= "" data-lazy-src="/assets/image-20240515195457616.png" alt="image-20240515195457616"> </p>
<h3 id="日志管理"><a href="#日志管理" class="headerlink" title="日志管理"></a>日志管理</h3><p>登录日志</p>
<ul>
<li>记录用户的登录信息，包括登录时间和地点（IP地址）。</li>
<li>帮助管理员监控登录行为，及时发现任何可疑的登录尝试。</li>
<li>同样提供搜索和筛选功能，方便查找特定用户的登录历史。</li>
</ul>
<p><img src= "" data-lazy-src="/assets/image-20240515195520979.png" alt="image-20240515195520979" style="zoom:90%;" /> </p>
<p>操作日志</p>
<ul>
<li>记录用户在系统中的所有操作，如查看、修改数据等。</li>
<li>帮助管理员检查谁做了什么，以及何时做的，确保数据准确无误。</li>
<li>可以快速搜索和找到特定的操作记录，便于管理和审查。</li>
</ul>
<p><img src= "" data-lazy-src="/assets/image-20240515195525287.png" alt="image-20240515195525287" style="zoom:80%;" /> </p>
<h2 id="系统监控"><a href="#系统监控" class="headerlink" title="系统监控"></a>系统监控</h2><h3 id="监控相关"><a href="#监控相关" class="headerlink" title="监控相关"></a>监控相关</h3><p>若依提供了一些列强大的监控工具，能够帮助开发者和运维快速了解应用程序的性能状态。</p>
<p><img src= "" data-lazy-src="/assets/image-20240515195822097.png" alt="image-20240515195822097"> </p>
<ol>
<li><strong>在线用户</strong>：<ul>
<li>管理员可以看到当前谁在系统里，他们什么时候登录的，从哪里登录的，属于哪个部门。</li>
<li>如果有人没权限还赖着不走，管理员可以一键让他们下线，保证系统的安全。</li>
</ul>
</li>
<li><strong>数据监控</strong>：<ul>
<li>管理员可以实时看到系统的各项指标，比如资源使用情况，数据库状态等。</li>
<li>通过图表可以直观地看出系统是否健康，如果出现问题，系统会发出警报。</li>
</ul>
</li>
<li><strong>服务监控</strong>：<ul>
<li>管理员可以监控系统中各个服务是否正常运行，以及它们的性能指标。</li>
<li>如果服务出现问题，系统会立即通知管理员，并通过仪表板展示，方便管理员快速了解情况。</li>
</ul>
</li>
<li><strong>缓存监控</strong>：<ul>
<li>管理员可以监控系统的缓存使用情况，比如缓存是否经常被用到，缓存的大小等。</li>
<li>系统还可以自动清理缓存，保持数据的新鲜度，如果缓存有问题，也会发出警报。</li>
</ul>
</li>
</ol>
<h3 id="定时任务"><a href="#定时任务" class="headerlink" title="定时任务"></a>定时任务</h3><h4 id="介绍-1"><a href="#介绍-1" class="headerlink" title="介绍"></a>介绍</h4><p>若依为定时任务功能提供方便友好的web界面，实现动态管理任务。</p>
<p><img src= "" data-lazy-src="/assets/image-20240515195859181.png" alt="image-20240515195859181"> </p>
<h4 id="案例-2"><a href="#案例-2" class="headerlink" title="案例"></a>案例</h4><p>每间隔5秒，控制台输出系统时间。</p>
<p><img src= "" data-lazy-src="/assets/image-20240515212217472.png" alt="image-20240515212217472"> </p>
<p>实现步骤：</p>
<p>①创建任务类<br><img src= "" data-lazy-src="/assets/image-20240515200554019.png" alt="image-20240515200554019"> </p>
<p>②添加任务规则</p>
<p><img src= "" data-lazy-src="/assets/image-20240515200608310.png" alt="image-20240515200608310"> </p>
<ul>
<li>任务名称：自定义，如：定时查询任务状态</li>
<li>任务分组：根据字典<code>sys_job_group</code>配置，可自行进行配置</li>
<li>调用目标字符串：设置后台任务方法名称参数</li>
<li>执行表达式：可查询官方<code>cron</code>表达式介绍</li>
<li>执行策略：定时任务自定义执行策略</li>
<li>并发执行：是否需要多个任务间同时执行</li>
</ul>
<p>③启动任务</p>
<p><img src= "" data-lazy-src="/assets/image-20240515212230091.png" alt="image-20240515212230091">  </p>
<h2 id="系统工具"><a href="#系统工具" class="headerlink" title="系统工具"></a>系统工具</h2><h3 id="表单构建"><a href="#表单构建" class="headerlink" title="表单构建"></a>表单构建</h3><h4 id="介绍-2"><a href="#介绍-2" class="headerlink" title="介绍"></a>介绍</h4><ul>
<li>允许用户通过拖放等可视化操作创建表单，比如用来收集数据的表格或调查问卷。</li>
<li>可以自定义表单的各个部分，比如添加不同的输入项和设置验证规则，无需编写代码。</li>
<li>提供了导出数据、导入数据、分享表单和设置权限的功能，方便数据管理和共享。</li>
</ul>
<p><img src= "" data-lazy-src="/assets/image-20240515201246417.png" alt="image-20240515201246417"> </p>
<h4 id="案例-3"><a href="#案例-3" class="headerlink" title="案例"></a>案例</h4><p>通过表单构建工具，单独制作一个添加课程的表单页面。</p>
<p><img src= "" data-lazy-src="/assets/image-20240515212304226.png" alt="image-20240515212304226"> </p>
<p>实现步骤：</p>
<p>①制作表单并导出<br><img src= "" data-lazy-src="/assets/image-20240515201358208.png" alt="image-20240515201358208"></p>
<p>②复制到前端工程<br><img src= "" data-lazy-src="/assets/image-20240515201427300.png" alt="image-20240515201427300"> </p>
<p>③创建动态菜单</p>
<p><img src= "" data-lazy-src="/assets/image-20240515201440877.png" alt="image-20240515201440877"> </p>
<h3 id="代码生成-1"><a href="#代码生成-1" class="headerlink" title="代码生成"></a>代码生成</h3><ul>
<li>自动化工具，可以快速生成项目中常用的代码，如数据库操作类、后端控制器、前端页面等。</li>
<li>支持根据数据库的表结构反向生成代码，减少手动编写的工作量。</li>
<li>提供三种生成模板：单表、 <span style='color:red'>树表</span>、主子表（一对多），可以生成适用于Spring Boot、MyBatis等流行框架的代码，提高开发效率和代码质量。</li>
<li>树表是一种展示层级数据的表格，能展开折叠，清晰呈现父子关系，便于管理。</li>
</ul>
<p><img src= "" data-lazy-src="/assets/image-20240515201619313.png" alt="image-20240515201619313"> </p>
<p>代码生成配置主表实现细节：</p>
<p><img src= "" data-lazy-src="/assets/image-20240515201640870.png" alt="image-20240515201640870"> </p>
<h3 id="系统接口"><a href="#系统接口" class="headerlink" title="系统接口"></a>系统接口</h3><ul>
<li>Swagger，能够自动生成 API 的同步在线文档，并提供Web界面进行接口调用和测试。</li>
</ul>
<p><img src= "" data-lazy-src="/assets/image-20240515201705896.png" alt="image-20240515201705896"> </p>
<h1 id="项目结构"><a href="#项目结构" class="headerlink" title="项目结构"></a>项目结构</h1><p>在功能的讲解过程中，涉及的前后端项目的结构和配置文件，我们还比较陌生，为了更好的使用若依进行项目开发，所以接下来，我们开始进入项目结构这部分内容的学习</p>
<h2 id="后端结构"><a href="#后端结构" class="headerlink" title="后端结构"></a>后端结构</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line">com.ruoyi</span><br><span class="line">├── ruoyi-admin      <span class="comment">// 后台服务模块</span></span><br><span class="line">│       └── web                           <span class="comment">// 内置功能的表现层</span></span><br><span class="line">│       └── RuoYiApplication              <span class="comment">// 若依项目启动类    </span></span><br><span class="line">├── ruoyi-common     <span class="comment">// 通用工具模块</span></span><br><span class="line">│       └── annotation                    <span class="comment">// 自定义注解</span></span><br><span class="line">│       └── config                        <span class="comment">// 全局配置</span></span><br><span class="line">│       └── constant                      <span class="comment">// 通用常量</span></span><br><span class="line">│       └── core                          <span class="comment">// 核心控制</span></span><br><span class="line">│       └── enums                         <span class="comment">// 通用枚举</span></span><br><span class="line">│       └── exception                     <span class="comment">// 通用异常</span></span><br><span class="line">│       └── filter                        <span class="comment">// 过滤器处理</span></span><br><span class="line">│       └── utils                         <span class="comment">// 通用类处理</span></span><br><span class="line">│       └── xss                           <span class="comment">// 自定义xss校验</span></span><br><span class="line">├── ruoyi-framework  <span class="comment">// 框架核心模块</span></span><br><span class="line">│       └── aspectj                       <span class="comment">// AOP配置</span></span><br><span class="line">│       └── config                        <span class="comment">// 系统配置</span></span><br><span class="line">│       └── datasource                    <span class="comment">// 多数据源配置 </span></span><br><span class="line">│       └── interceptor                   <span class="comment">// 拦截器</span></span><br><span class="line">│       └── manager                       <span class="comment">// 异步处理</span></span><br><span class="line">│       └── security                      <span class="comment">// 权限控制</span></span><br><span class="line">│       └── web                           <span class="comment">// 前端控制</span></span><br><span class="line">├── ruoyi-generator  <span class="comment">// 代码生成模块（可移除）              </span></span><br><span class="line">├── ruoyi-quartz     <span class="comment">// 定时任务模块（可移除）          </span></span><br><span class="line">├── ruoyi-system     <span class="comment">// 系统代码模块</span></span><br><span class="line">│       └── domain                        <span class="comment">// 系统代码的实体类</span></span><br><span class="line">│       └── mapper                        <span class="comment">// 系统代码的持久层</span></span><br><span class="line">│       └── service                       <span class="comment">// 系统代码的业务层</span></span><br></pre></td></tr></table></figure>
<p><img src= "" data-lazy-src="/assets/image-20240515202429752.png" alt="image-20240515202429752"> </p>
<h2 id="项目中配置"><a href="#项目中配置" class="headerlink" title="项目中配置"></a>项目中配置</h2><p>项目中的配置文件都在ruoyi-admin模块下，如下图：</p>
<p><img src= "" data-lazy-src="/assets/image-20240515202447038.png" alt="image-20240515202447038">  </p>
<ul>
<li>i18n：国际化处理</li>
<li>META-INF：存储了项目的元信息（<em>描述数据的数据</em>），无需修改</li>
<li>mybatis：mybatis相关的配置信息</li>
<li>application.yml：项目中的核心配置</li>
<li>application-druid.yml：数据库连接配置</li>
<li>banner.txt：默认的banner图标信息，项目启动，控制台打印显示</li>
<li>logback.xml：日志配置</li>
</ul>
<p>最主要的两个配置文件：application.yml</p>
<figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 项目相关配置</span></span><br><span class="line"><span class="attr">ruoyi:</span></span><br><span class="line">  <span class="comment"># 名称</span></span><br><span class="line">  <span class="attr">name:</span> <span class="string">RuoYi</span></span><br><span class="line">  <span class="comment"># 版本</span></span><br><span class="line">  <span class="attr">version:</span> <span class="number">3.8</span><span class="number">.7</span></span><br><span class="line">  <span class="comment"># 版权年份</span></span><br><span class="line">  <span class="attr">copyrightYear:</span> <span class="number">2024</span></span><br><span class="line">  <span class="comment"># 文件路径 示例（ Windows配置D:/ruoyi/uploadPath，Linux配置 /home/ruoyi/uploadPath）</span></span><br><span class="line">  <span class="attr">profile:</span> <span class="string">D:/ruoyi/uploadPath</span></span><br><span class="line">  <span class="comment"># 获取ip地址开关</span></span><br><span class="line">  <span class="attr">addressEnabled:</span> <span class="literal">false</span></span><br><span class="line">  <span class="comment"># 验证码类型 math 数字计算 char 字符验证</span></span><br><span class="line">  <span class="attr">captchaType:</span> <span class="string">math</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 开发环境配置</span></span><br><span class="line"><span class="attr">server:</span></span><br><span class="line">  <span class="comment"># 服务器的HTTP端口，默认为8080</span></span><br><span class="line">  <span class="attr">port:</span> <span class="number">8080</span></span><br><span class="line">  <span class="attr">servlet:</span></span><br><span class="line">    <span class="comment"># 应用的访问路径</span></span><br><span class="line">    <span class="attr">context-path:</span> <span class="string">/</span></span><br><span class="line">  <span class="attr">tomcat:</span></span><br><span class="line">    <span class="comment"># tomcat的URI编码</span></span><br><span class="line">    <span class="attr">uri-encoding:</span> <span class="string">UTF-8</span></span><br><span class="line">    <span class="comment"># 连接数满后的排队数，默认为100</span></span><br><span class="line">    <span class="attr">accept-count:</span> <span class="number">1000</span></span><br><span class="line">    <span class="attr">threads:</span></span><br><span class="line">      <span class="comment"># tomcat最大线程数，默认为200</span></span><br><span class="line">      <span class="attr">max:</span> <span class="number">800</span></span><br><span class="line">      <span class="comment"># Tomcat启动初始化的线程数，默认值10</span></span><br><span class="line">      <span class="attr">min-spare:</span> <span class="number">100</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 日志配置</span></span><br><span class="line"><span class="attr">logging:</span></span><br><span class="line">  <span class="attr">level:</span></span><br><span class="line">    <span class="attr">com.ruoyi:</span> <span class="string">debug</span></span><br><span class="line">    <span class="attr">org.springframework:</span> <span class="string">warn</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 用户配置</span></span><br><span class="line"><span class="attr">user:</span></span><br><span class="line">  <span class="attr">password:</span></span><br><span class="line">    <span class="comment"># 密码最大错误次数</span></span><br><span class="line">    <span class="attr">maxRetryCount:</span> <span class="number">5</span></span><br><span class="line">    <span class="comment"># 密码锁定时间（默认10分钟）</span></span><br><span class="line">    <span class="attr">lockTime:</span> <span class="number">10</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Spring配置</span></span><br><span class="line"><span class="attr">spring:</span></span><br><span class="line">  <span class="comment"># 资源信息</span></span><br><span class="line">  <span class="attr">messages:</span></span><br><span class="line">    <span class="comment"># 国际化资源文件路径</span></span><br><span class="line">    <span class="attr">basename:</span> <span class="string">i18n/messages</span></span><br><span class="line">  <span class="attr">profiles:</span></span><br><span class="line">    <span class="attr">active:</span> <span class="string">druid</span></span><br><span class="line">  <span class="comment"># 文件上传</span></span><br><span class="line">  <span class="attr">servlet:</span></span><br><span class="line">    <span class="attr">multipart:</span></span><br><span class="line">      <span class="comment"># 单个文件大小</span></span><br><span class="line">      <span class="attr">max-file-size:</span> <span class="string">10MB</span></span><br><span class="line">      <span class="comment"># 设置总上传的文件大小</span></span><br><span class="line">      <span class="attr">max-request-size:</span> <span class="string">20MB</span></span><br><span class="line">  <span class="comment"># 服务模块</span></span><br><span class="line">  <span class="attr">devtools:</span></span><br><span class="line">    <span class="attr">restart:</span></span><br><span class="line">      <span class="comment"># 热部署开关</span></span><br><span class="line">      <span class="attr">enabled:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># redis 配置</span></span><br><span class="line">  <span class="attr">redis:</span></span><br><span class="line">    <span class="comment"># 地址</span></span><br><span class="line">    <span class="attr">host:</span> <span class="string">localhost</span></span><br><span class="line">    <span class="comment"># 端口，默认为6379</span></span><br><span class="line">    <span class="attr">port:</span> <span class="number">6379</span></span><br><span class="line">    <span class="comment"># 数据库索引</span></span><br><span class="line">    <span class="attr">database:</span> <span class="number">0</span></span><br><span class="line">    <span class="comment"># 密码</span></span><br><span class="line">    <span class="attr">password:</span> <span class="number">123456</span></span><br><span class="line">    <span class="comment"># 连接超时时间</span></span><br><span class="line">    <span class="attr">timeout:</span> <span class="string">10s</span></span><br><span class="line">    <span class="attr">lettuce:</span></span><br><span class="line">      <span class="attr">pool:</span></span><br><span class="line">        <span class="comment"># 连接池中的最小空闲连接</span></span><br><span class="line">        <span class="attr">min-idle:</span> <span class="number">0</span></span><br><span class="line">        <span class="comment"># 连接池中的最大空闲连接</span></span><br><span class="line">        <span class="attr">max-idle:</span> <span class="number">8</span></span><br><span class="line">        <span class="comment"># 连接池的最大数据库连接数</span></span><br><span class="line">        <span class="attr">max-active:</span> <span class="number">8</span></span><br><span class="line">        <span class="comment"># #连接池最大阻塞等待时间（使用负值表示没有限制）</span></span><br><span class="line">        <span class="attr">max-wait:</span> <span class="string">-1ms</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># token配置</span></span><br><span class="line"><span class="attr">token:</span></span><br><span class="line">  <span class="comment"># 令牌自定义标识</span></span><br><span class="line">  <span class="attr">header:</span> <span class="string">Authorization</span></span><br><span class="line">  <span class="comment"># 令牌密钥</span></span><br><span class="line">  <span class="attr">secret:</span> <span class="string">abcdefghijklmnopqrstuvwxyz</span></span><br><span class="line">  <span class="comment"># 令牌有效期（默认30分钟）</span></span><br><span class="line">  <span class="attr">expireTime:</span> <span class="number">30</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># MyBatis配置</span></span><br><span class="line"><span class="attr">mybatis:</span></span><br><span class="line">  <span class="comment"># 搜索指定包别名</span></span><br><span class="line">  <span class="attr">typeAliasesPackage:</span> <span class="string">com.ruoyi.**.domain</span></span><br><span class="line">  <span class="comment"># 配置mapper的扫描，找到所有的mapper.xml映射文件</span></span><br><span class="line">  <span class="attr">mapperLocations:</span> <span class="string">classpath*:mapper/**/*Mapper.xml</span></span><br><span class="line">  <span class="comment"># 加载全局的配置文件</span></span><br><span class="line">  <span class="attr">configLocation:</span> <span class="string">classpath:mybatis/mybatis-config.xml</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># PageHelper分页插件</span></span><br><span class="line"><span class="attr">pagehelper:</span></span><br><span class="line">  <span class="attr">helperDialect:</span> <span class="string">mysql</span></span><br><span class="line">  <span class="attr">supportMethodsArguments:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">params:</span> <span class="string">count=countSql</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Swagger配置</span></span><br><span class="line"><span class="attr">swagger:</span></span><br><span class="line">  <span class="comment"># 是否开启swagger</span></span><br><span class="line">  <span class="attr">enabled:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 请求前缀</span></span><br><span class="line">  <span class="attr">pathMapping:</span> <span class="string">/dev-api</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 防止XSS攻击</span></span><br><span class="line"><span class="attr">xss:</span></span><br><span class="line">  <span class="comment"># 过滤开关</span></span><br><span class="line">  <span class="attr">enabled:</span> <span class="literal">true</span></span><br><span class="line">  <span class="comment"># 排除链接（多个用逗号分隔）</span></span><br><span class="line">  <span class="attr">excludes:</span> <span class="string">/system/notice</span></span><br><span class="line">  <span class="comment"># 匹配链接</span></span><br><span class="line">  <span class="attr">urlPatterns:</span> <span class="string">/system/*,/monitor/*,/tool/*</span></span><br></pre></td></tr></table></figure>
<h2 id="模块依赖关系"><a href="#模块依赖关系" class="headerlink" title="模块依赖关系"></a>模块依赖关系</h2><p>各个模块之间的依赖关系：</p>
<p><img src= "" data-lazy-src="/assets/image-20240515202002135.png" alt="image-20240515202002135">  </p>
<h2 id="前端结构"><a href="#前端结构" class="headerlink" title="前端结构"></a>前端结构</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line">ruoyi-vue3</span><br><span class="line">├── bin                        <span class="comment">// 执行脚本</span></span><br><span class="line">├── html                       <span class="comment">// IE低版本提示页</span></span><br><span class="line">├── node_modules               <span class="comment">// 第三方依赖库</span></span><br><span class="line">├── public                     <span class="comment">// 公共资源</span></span><br><span class="line">│   ├── favicon.<span class="property">ico</span>            <span class="comment">// favicon图标</span></span><br><span class="line">├── src                        <span class="comment">// 源代码</span></span><br><span class="line">│   ├── api                    <span class="comment">// 所有请求</span></span><br><span class="line">│   ├── /assets                 <span class="comment">// 静态资源</span></span><br><span class="line">│   ├── components             <span class="comment">// 全局公用组件</span></span><br><span class="line">│   ├── directive              <span class="comment">// 全局指令</span></span><br><span class="line">│   ├── layout                 <span class="comment">// 布局</span></span><br><span class="line">│   ├── plugins                <span class="comment">// 通用插件</span></span><br><span class="line">│   ├── router                 <span class="comment">// 路由配置</span></span><br><span class="line">│   ├── store                  <span class="comment">// 状态管理</span></span><br><span class="line">│   ├── utils                  <span class="comment">// 全局公用方法</span></span><br><span class="line">│   ├── views                  <span class="comment">// 视图组件</span></span><br><span class="line">│   ├── <span class="title class_">App</span>.<span class="property">vue</span>                <span class="comment">// 入口组件</span></span><br><span class="line">│   ├── main.<span class="property">js</span>                <span class="comment">// 入口文件</span></span><br><span class="line">│   ├── permission.<span class="property">js</span>          <span class="comment">// 权限管理</span></span><br><span class="line">│   └── settings.<span class="property">js</span>            <span class="comment">// 系统配置</span></span><br><span class="line">├── vite                       <span class="comment">// 构建工具</span></span><br><span class="line">├── .<span class="property">env</span>.<span class="property">development</span>           <span class="comment">// 开发环境配置</span></span><br><span class="line">├── .<span class="property">env</span>.<span class="property">production</span>            <span class="comment">// 生产环境配置</span></span><br><span class="line">├── .<span class="property">env</span>.<span class="property">staging</span>               <span class="comment">// 测试环境配置</span></span><br><span class="line">├── .<span class="property">gitignore</span>                 <span class="comment">// git 忽略项</span></span><br><span class="line">├── index.<span class="property">html</span>                 <span class="comment">// 入口页面</span></span><br><span class="line">├── package.<span class="property">json</span>               <span class="comment">// 项目配置文件（相当于pom.xml）</span></span><br><span class="line">└── vue.<span class="property">config</span>.<span class="property">js</span>              <span class="comment">// Vue项目的配置信息（相当于application.yml）</span></span><br></pre></td></tr></table></figure>
<p><img src= "" data-lazy-src="/assets/image-20240515202411640.png" alt="image-20240515202411640"> </p>
<h2 id="表结构介绍"><a href="#表结构介绍" class="headerlink" title="表结构介绍"></a>表结构介绍</h2><p><code>ruoyi-vue</code>数据库设计包含了多个表结构，用于支持系统的各种功能模块。</p>
<p>这些表可以根据它们的功能和用途进行分类，以便在后期使用时能够快速定位和理解。以下是对这些表结构的分类和简要说明：</p>
<p><img src= "" data-lazy-src="/assets/image-20240515202517972.png" alt="image-20240515202517972"> </p>
<p><img src= "" data-lazy-src="/assets/ruoyi-vue.png" alt="ruoyi-vue"> </p>
<h1 id="源码阅读"><a href="#源码阅读" class="headerlink" title="源码阅读"></a>源码阅读</h1><p>本章我们将围绕入门案例生成的课程管理进行讲解，包含前后端代码的分析，以及前后端代码交互的流程，通过这部分的学习，不仅能让我们掌握若依的基础业务逻辑，在此基础上还能为我们日后的定制开发提供强有力的支撑。</p>
<h2 id="前端代码分析"><a href="#前端代码分析" class="headerlink" title="前端代码分析"></a>前端代码分析</h2><p>找到src/views/course/course/index.vue文件，护理项目的前端代码已经添加了详细的注释，如下：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br></pre></td><td class="code"><pre><span class="line">&lt;template&gt;</span><br><span class="line">  &lt;div class=&quot;app-container&quot;&gt;</span><br><span class="line"></span><br><span class="line">    &lt;!-- 搜索表单 start --&gt;</span><br><span class="line">    &lt;el-form :model=&quot;queryParams&quot; ref=&quot;queryRef&quot; :inline=&quot;true&quot; v-show=&quot;showSearch&quot; label-width=&quot;68px&quot;&gt;   </span><br><span class="line">      &lt;el-form-item label=&quot;课程编码&quot; prop=&quot;code&quot;&gt;</span><br><span class="line">        &lt;el-input</span><br><span class="line">          v-model=&quot;queryParams.code&quot;</span><br><span class="line">          placeholder=&quot;请输入课程编码&quot;</span><br><span class="line">          clearable</span><br><span class="line">          @keyup.enter=&quot;handleQuery&quot;</span><br><span class="line">        /&gt;</span><br><span class="line">      &lt;/el-form-item&gt;</span><br><span class="line">      &lt;el-form-item label=&quot;课程学科&quot; prop=&quot;subject&quot;&gt;</span><br><span class="line">        &lt;el-select v-model=&quot;queryParams.subject&quot; placeholder=&quot;请选择课程学科&quot; clearable&gt;</span><br><span class="line">          &lt;el-option</span><br><span class="line">            v-for=&quot;dict in course_subject&quot;</span><br><span class="line">            :key=&quot;dict.value&quot;</span><br><span class="line">            :label=&quot;dict.label&quot;</span><br><span class="line">            :value=&quot;dict.value&quot;</span><br><span class="line">          /&gt;</span><br><span class="line">        &lt;/el-select&gt;</span><br><span class="line">      &lt;/el-form-item&gt;</span><br><span class="line">      &lt;el-form-item label=&quot;课程名称&quot; prop=&quot;name&quot;&gt;</span><br><span class="line">        &lt;el-input</span><br><span class="line">          v-model=&quot;queryParams.name&quot;</span><br><span class="line">          placeholder=&quot;请输入课程名称&quot;</span><br><span class="line">          clearable</span><br><span class="line">          @keyup.enter=&quot;handleQuery&quot;</span><br><span class="line">        /&gt;</span><br><span class="line">      &lt;/el-form-item&gt;</span><br><span class="line">      &lt;el-form-item label=&quot;适用人群&quot; prop=&quot;applicablePerson&quot;&gt;</span><br><span class="line">        &lt;el-input</span><br><span class="line">          v-model=&quot;queryParams.applicablePerson&quot;</span><br><span class="line">          placeholder=&quot;请输入适用人群&quot;</span><br><span class="line">          clearable</span><br><span class="line">          @keyup.enter=&quot;handleQuery&quot;</span><br><span class="line">        /&gt;</span><br><span class="line">      &lt;/el-form-item&gt;</span><br><span class="line">      &lt;el-form-item&gt;</span><br><span class="line">        &lt;el-button type=&quot;primary&quot; icon=&quot;Search&quot; @click=&quot;handleQuery&quot;&gt;搜索&lt;/el-button&gt;</span><br><span class="line">        &lt;el-button icon=&quot;Refresh&quot; @click=&quot;resetQuery&quot;&gt;重置&lt;/el-button&gt;</span><br><span class="line">      &lt;/el-form-item&gt;</span><br><span class="line">    &lt;/el-form&gt;</span><br><span class="line">    &lt;!-- 搜索表单 end --&gt;</span><br><span class="line"></span><br><span class="line">    &lt;!-- 按钮区域 start --&gt;</span><br><span class="line">    &lt;el-row :gutter=&quot;10&quot; class=&quot;mb8&quot;&gt;</span><br><span class="line">      &lt;el-col :span=&quot;1.5&quot;&gt;</span><br><span class="line">        &lt;el-button</span><br><span class="line">          type=&quot;primary&quot;</span><br><span class="line">          plain</span><br><span class="line">          icon=&quot;Plus&quot;</span><br><span class="line">          @click=&quot;handleAdd&quot;</span><br><span class="line">          v-hasPermi=&quot;[&#x27;course:course:add&#x27;]&quot;</span><br><span class="line">        &gt;新增&lt;/el-button&gt;</span><br><span class="line">      &lt;/el-col&gt;</span><br><span class="line">      &lt;el-col :span=&quot;1.5&quot;&gt;</span><br><span class="line">        &lt;el-button</span><br><span class="line">          type=&quot;success&quot;</span><br><span class="line">          plain</span><br><span class="line">          icon=&quot;Edit&quot;</span><br><span class="line">          :disabled=&quot;single&quot;</span><br><span class="line">          @click=&quot;handleUpdate&quot;</span><br><span class="line">          v-hasPermi=&quot;[&#x27;course:course:edit&#x27;]&quot;</span><br><span class="line">        &gt;修改&lt;/el-button&gt;</span><br><span class="line">      &lt;/el-col&gt;</span><br><span class="line">      &lt;el-col :span=&quot;1.5&quot;&gt;</span><br><span class="line">        &lt;el-button</span><br><span class="line">          type=&quot;danger&quot;</span><br><span class="line">          plain</span><br><span class="line">          icon=&quot;Delete&quot;</span><br><span class="line">          :disabled=&quot;multiple&quot;</span><br><span class="line">          @click=&quot;handleDelete&quot;</span><br><span class="line">          v-hasPermi=&quot;[&#x27;course:course:remove&#x27;]&quot;</span><br><span class="line">        &gt;删除&lt;/el-button&gt;</span><br><span class="line">      &lt;/el-col&gt;</span><br><span class="line">      &lt;el-col :span=&quot;1.5&quot;&gt;</span><br><span class="line">        &lt;el-button</span><br><span class="line">          type=&quot;warning&quot;</span><br><span class="line">          plain</span><br><span class="line">          icon=&quot;Download&quot;</span><br><span class="line">          @click=&quot;handleExport&quot;</span><br><span class="line">          v-hasPermi=&quot;[&#x27;course:course:export&#x27;]&quot;</span><br><span class="line">        &gt;导出&lt;/el-button&gt;</span><br><span class="line">      &lt;/el-col&gt;</span><br><span class="line">      &lt;right-toolbar v-model:showSearch=&quot;showSearch&quot; @queryTable=&quot;getList&quot;&gt;&lt;/right-toolbar&gt;</span><br><span class="line">    &lt;/el-row&gt;</span><br><span class="line">    &lt;!-- 按钮区域end --&gt;</span><br><span class="line"></span><br><span class="line">    &lt;!-- 数据展示表格 start --&gt;</span><br><span class="line">    &lt;el-table v-loading=&quot;loading&quot; :data=&quot;courseList&quot; @selection-change=&quot;handleSelectionChange&quot;&gt; </span><br><span class="line">      &lt;el-table-column type=&quot;selection&quot; width=&quot;55&quot; align=&quot;center&quot; /&gt;</span><br><span class="line">      &lt;el-table-column label=&quot;课程id&quot; align=&quot;center&quot; prop=&quot;id&quot; /&gt;</span><br><span class="line">      &lt;el-table-column label=&quot;课程编码&quot; align=&quot;center&quot; prop=&quot;code&quot; /&gt;</span><br><span class="line">      &lt;el-table-column label=&quot;课程学科&quot; align=&quot;center&quot; prop=&quot;subject&quot;&gt;</span><br><span class="line">        &lt;template #default=&quot;scope&quot;&gt;</span><br><span class="line">          &lt;dict-tag :options=&quot;course_subject&quot; :value=&quot;scope.row.subject&quot;/&gt;</span><br><span class="line">        &lt;/template&gt;</span><br><span class="line">      &lt;/el-table-column&gt;</span><br><span class="line">      &lt;el-table-column label=&quot;课程名称&quot; align=&quot;center&quot; prop=&quot;name&quot; /&gt;</span><br><span class="line">      &lt;el-table-column label=&quot;价格&quot; align=&quot;center&quot; prop=&quot;price&quot; /&gt;</span><br><span class="line">      &lt;el-table-column label=&quot;适用人群&quot; align=&quot;center&quot; prop=&quot;applicablePerson&quot; /&gt;</span><br><span class="line">      &lt;el-table-column label=&quot;课程介绍&quot; align=&quot;center&quot; prop=&quot;info&quot; /&gt;</span><br><span class="line">      &lt;el-table-column label=&quot;操作&quot; align=&quot;center&quot; class-name=&quot;small-padding fixed-width&quot;&gt;</span><br><span class="line">        &lt;template #default=&quot;scope&quot;&gt;</span><br><span class="line">          &lt;el-button link type=&quot;primary&quot; icon=&quot;Edit&quot; @click=&quot;handleUpdate(scope.row)&quot; v-hasPermi=&quot;[&#x27;course:course:edit&#x27;]&quot;&gt;修改&lt;/el-button&gt;</span><br><span class="line">          &lt;el-button link type=&quot;primary&quot; icon=&quot;Delete&quot; @click=&quot;handleDelete(scope.row)&quot; v-hasPermi=&quot;[&#x27;course:course:remove&#x27;]&quot;&gt;删除&lt;/el-button&gt;</span><br><span class="line">        &lt;/template&gt;</span><br><span class="line">      &lt;/el-table-column&gt;</span><br><span class="line">    &lt;/el-table&gt;</span><br><span class="line">    &lt;!-- 数据展示表格 end --&gt;</span><br><span class="line">    </span><br><span class="line">    &lt;!-- 分页区域 start --&gt;</span><br><span class="line">    &lt;pagination</span><br><span class="line">      v-show=&quot;total&gt;0&quot;</span><br><span class="line">      :total=&quot;total&quot;</span><br><span class="line">      v-model:page=&quot;queryParams.pageNum&quot;</span><br><span class="line">      v-model:limit=&quot;queryParams.pageSize&quot;</span><br><span class="line">      @pagination=&quot;getList&quot;</span><br><span class="line">    /&gt;</span><br><span class="line">    &lt;!-- 分页区域 end --&gt;</span><br><span class="line"></span><br><span class="line">    &lt;!-- 添加或修改课程管理对话框 --&gt;</span><br><span class="line">    &lt;el-dialog :title=&quot;title&quot; v-model=&quot;open&quot; width=&quot;500px&quot; append-to-body&gt;</span><br><span class="line">      &lt;el-form ref=&quot;courseRef&quot; :model=&quot;form&quot; :rules=&quot;rules&quot; label-width=&quot;80px&quot;&gt;</span><br><span class="line">        &lt;el-form-item label=&quot;课程编码&quot; prop=&quot;code&quot;&gt;</span><br><span class="line">          &lt;el-input v-model=&quot;form.code&quot; placeholder=&quot;请输入课程编码&quot; /&gt;</span><br><span class="line">        &lt;/el-form-item&gt;</span><br><span class="line">        &lt;el-form-item label=&quot;课程学科&quot; prop=&quot;subject&quot;&gt;</span><br><span class="line">          &lt;el-select v-model=&quot;form.subject&quot; placeholder=&quot;请选择课程学科&quot;&gt;</span><br><span class="line">            &lt;el-option</span><br><span class="line">              v-for=&quot;dict in course_subject&quot;</span><br><span class="line">              :key=&quot;dict.value&quot;</span><br><span class="line">              :label=&quot;dict.label&quot;</span><br><span class="line">              :value=&quot;dict.value&quot;</span><br><span class="line">            &gt;&lt;/el-option&gt;</span><br><span class="line">          &lt;/el-select&gt;</span><br><span class="line">        &lt;/el-form-item&gt;</span><br><span class="line">        &lt;el-form-item label=&quot;课程名称&quot; prop=&quot;name&quot;&gt;</span><br><span class="line">          &lt;el-input v-model=&quot;form.name&quot; placeholder=&quot;请输入课程名称&quot; /&gt;</span><br><span class="line">        &lt;/el-form-item&gt;</span><br><span class="line">        &lt;el-form-item label=&quot;价格&quot; prop=&quot;price&quot;&gt;</span><br><span class="line">          &lt;el-input v-model=&quot;form.price&quot; placeholder=&quot;请输入价格&quot; /&gt;</span><br><span class="line">        &lt;/el-form-item&gt;</span><br><span class="line">        &lt;el-form-item label=&quot;适用人群&quot; prop=&quot;applicablePerson&quot;&gt;</span><br><span class="line">          &lt;el-input v-model=&quot;form.applicablePerson&quot; placeholder=&quot;请输入适用人群&quot; /&gt;</span><br><span class="line">        &lt;/el-form-item&gt;</span><br><span class="line">        &lt;el-form-item label=&quot;课程介绍&quot; prop=&quot;info&quot;&gt;</span><br><span class="line">          &lt;el-input v-model=&quot;form.info&quot; placeholder=&quot;请输入课程介绍&quot; /&gt;</span><br><span class="line">        &lt;/el-form-item&gt;</span><br><span class="line">      &lt;/el-form&gt;</span><br><span class="line">      &lt;template #footer&gt;</span><br><span class="line">        &lt;div class=&quot;dialog-footer&quot;&gt;</span><br><span class="line">          &lt;el-button type=&quot;primary&quot; @click=&quot;submitForm&quot;&gt;确 定&lt;/el-button&gt;</span><br><span class="line">          &lt;el-button @click=&quot;cancel&quot;&gt;取 消&lt;/el-button&gt;</span><br><span class="line">        &lt;/div&gt;</span><br><span class="line">      &lt;/template&gt;</span><br><span class="line">    &lt;/el-dialog&gt;</span><br><span class="line">  &lt;/div&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;script setup name=&quot;Course&quot;&gt;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">// 引入后端api接口</span><br><span class="line">import &#123; listCourse, getCourse, delCourse, addCourse, updateCourse &#125; from &quot;@/api/course/course&quot;;</span><br><span class="line">// 获取当前实例代理对象，用于访问组件数据、方法</span><br><span class="line">const &#123; proxy &#125; = getCurrentInstance();</span><br><span class="line">// 获取课程学科的数据字典</span><br><span class="line">const &#123; course_subject &#125; = proxy.useDict(&#x27;course_subject&#x27;);</span><br><span class="line">// 列表数据</span><br><span class="line">const courseList = ref([]);</span><br><span class="line">// 是否显示弹框</span><br><span class="line">const open = ref(false);</span><br><span class="line">// 是否显示加载状态</span><br><span class="line">const loading = ref(true);</span><br><span class="line">// 是否显示搜索栏</span><br><span class="line">const showSearch = ref(true);</span><br><span class="line">// 复选框，被选中id的数组</span><br><span class="line">const ids = ref([]);</span><br><span class="line">// 复选框，是否单选，用于高亮修改、删除按钮</span><br><span class="line">const single = ref(true);</span><br><span class="line">// 复选框，是否多选，仅高亮删除按钮</span><br><span class="line">const multiple = ref(true);</span><br><span class="line">// 总（记录）条数</span><br><span class="line">const total = ref(0);</span><br><span class="line">// 用于区分新增、修改对话框标题</span><br><span class="line">const title = ref(&quot;&quot;);</span><br><span class="line">// 定义reactive响应式对象</span><br><span class="line">const data = reactive(&#123;</span><br><span class="line">  // 新增或修改表单数据</span><br><span class="line">  form: &#123;&#125;,</span><br><span class="line">  // 搜索条件参数</span><br><span class="line">  queryParams: &#123;</span><br><span class="line">    pageNum: 1,</span><br><span class="line">    pageSize: 10,</span><br><span class="line">    code: null,</span><br><span class="line">    subject: null,</span><br><span class="line">    name: null,</span><br><span class="line">    applicablePerson: null,</span><br><span class="line">  &#125;,</span><br><span class="line">  // 表单校验规则</span><br><span class="line">  rules: &#123;</span><br><span class="line">    code: [</span><br><span class="line">      &#123; required: true, message: &quot;课程编码不能为空&quot;, trigger: &quot;blur&quot; &#125;</span><br><span class="line">    ],</span><br><span class="line">    subject: [</span><br><span class="line">      &#123; required: true, message: &quot;课程学科不能为空&quot;, trigger: &quot;change&quot; &#125;</span><br><span class="line">    ],</span><br><span class="line">    name: [</span><br><span class="line">      &#123; required: true, message: &quot;课程名称不能为空&quot;, trigger: &quot;blur&quot; &#125;</span><br><span class="line">    ],</span><br><span class="line">    price: [</span><br><span class="line">      &#123; required: true, message: &quot;价格不能为空&quot;, trigger: &quot;blur&quot; &#125;</span><br><span class="line">    ],</span><br><span class="line">    applicablePerson: [</span><br><span class="line">      &#123; required: true, message: &quot;适用人群不能为空&quot;, trigger: &quot;blur&quot; &#125;</span><br><span class="line">    ],</span><br><span class="line">    info: [</span><br><span class="line">      &#123; required: true, message: &quot;课程介绍不能为空&quot;, trigger: &quot;blur&quot; &#125;</span><br><span class="line">    ],</span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br><span class="line">// 将data对象的三个属性，转换为ref响应式对象</span><br><span class="line">const &#123; queryParams, form, rules &#125; = toRefs(data);</span><br><span class="line"></span><br><span class="line">/** 查询课程管理列表 */</span><br><span class="line">function getList() &#123;</span><br><span class="line">  loading.value = true;</span><br><span class="line">  listCourse(queryParams.value).then(response =&gt; &#123;</span><br><span class="line">    courseList.value = response.rows;</span><br><span class="line">    total.value = response.total;</span><br><span class="line">    loading.value = false;</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">// 取消按钮</span><br><span class="line">function cancel() &#123;</span><br><span class="line">  open.value = false;</span><br><span class="line">  reset();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">// 表单重置</span><br><span class="line">function reset() &#123;</span><br><span class="line">  form.value = &#123;</span><br><span class="line">    id: null,</span><br><span class="line">    code: null,</span><br><span class="line">    subject: null,</span><br><span class="line">    name: null,</span><br><span class="line">    price: null,</span><br><span class="line">    applicablePerson: null,</span><br><span class="line">    info: null,</span><br><span class="line">    createTime: null,</span><br><span class="line">    updateTime: null</span><br><span class="line">  &#125;;</span><br><span class="line">  proxy.resetForm(&quot;courseRef&quot;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">/** 搜索按钮操作 */</span><br><span class="line">function handleQuery() &#123;</span><br><span class="line">  queryParams.value.pageNum = 1;</span><br><span class="line">  getList();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">/** 重置按钮操作 */</span><br><span class="line">function resetQuery() &#123;</span><br><span class="line">  proxy.resetForm(&quot;queryRef&quot;);</span><br><span class="line">  handleQuery();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">// 多选框选中数据</span><br><span class="line">function handleSelectionChange(selection) &#123;</span><br><span class="line">  ids.value = selection.map(item =&gt; item.id);</span><br><span class="line">  single.value = selection.length != 1;</span><br><span class="line">  multiple.value = !selection.length;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">/** 新增按钮操作 */</span><br><span class="line">function handleAdd() &#123;</span><br><span class="line">  reset();</span><br><span class="line">  open.value = true;</span><br><span class="line">  title.value = &quot;添加课程管理&quot;;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">/** 修改按钮操作 */</span><br><span class="line">function handleUpdate(row) &#123;</span><br><span class="line">  reset();</span><br><span class="line">  const _id = row.id || ids.value</span><br><span class="line">  getCourse(_id).then(response =&gt; &#123;</span><br><span class="line">    form.value = response.data;</span><br><span class="line">    open.value = true;</span><br><span class="line">    title.value = &quot;修改课程管理&quot;;</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">/** 提交按钮 */</span><br><span class="line">function submitForm() &#123;</span><br><span class="line">  proxy.$refs[&quot;courseRef&quot;].validate(valid =&gt; &#123;</span><br><span class="line">    if (valid) &#123;</span><br><span class="line">      if (form.value.id != null) &#123;</span><br><span class="line">        updateCourse(form.value).then(response =&gt; &#123;</span><br><span class="line">          proxy.$modal.msgSuccess(&quot;修改成功&quot;);</span><br><span class="line">          open.value = false;</span><br><span class="line">          getList();</span><br><span class="line">        &#125;);</span><br><span class="line">      &#125; else &#123;</span><br><span class="line">        addCourse(form.value).then(response =&gt; &#123;</span><br><span class="line">          proxy.$modal.msgSuccess(&quot;新增成功&quot;);</span><br><span class="line">          open.value = false;</span><br><span class="line">          getList();</span><br><span class="line">        &#125;);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">/** 删除按钮操作 */</span><br><span class="line">function handleDelete(row) &#123;</span><br><span class="line">  const _ids = row.id || ids.value;</span><br><span class="line">  proxy.$modal.confirm(&#x27;是否确认删除课程管理编号为&quot;&#x27; + _ids + &#x27;&quot;的数据项？&#x27;).then(function() &#123;</span><br><span class="line">    return delCourse(_ids);</span><br><span class="line">  &#125;).then(() =&gt; &#123;</span><br><span class="line">    getList();</span><br><span class="line">    proxy.$modal.msgSuccess(&quot;删除成功&quot;);</span><br><span class="line">  &#125;).catch(() =&gt; &#123;&#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">/** 导出按钮操作 */</span><br><span class="line">function handleExport() &#123;</span><br><span class="line">  proxy.download(&#x27;course/course/export&#x27;, &#123; </span><br><span class="line">    ...queryParams.value</span><br><span class="line">  &#125;, `course_$&#123;new Date().getTime()&#125;.xlsx`)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">// 页面加载时执行-查询课程管理列表</span><br><span class="line">getList();</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>
<h2 id="后端代码分析"><a href="#后端代码分析" class="headerlink" title="后端代码分析"></a>后端代码分析</h2><h3 id="CourseController"><a href="#CourseController" class="headerlink" title="CourseController"></a>CourseController</h3><p>ruoyi-admin模块下找到这个类：com.ruoyi.web.controller.course.CourseController里面有5个对应的方法接口，详细代码如下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.sky.course.controller;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.sky.common.annotation.Log;</span><br><span class="line"><span class="keyword">import</span> com.sky.common.core.controller.BaseController;</span><br><span class="line"><span class="keyword">import</span> com.sky.common.core.domain.AjaxResult;</span><br><span class="line"><span class="keyword">import</span> com.sky.common.core.page.TableDataInfo;</span><br><span class="line"><span class="keyword">import</span> com.sky.common.enums.BusinessType;</span><br><span class="line"><span class="keyword">import</span> com.sky.common.utils.poi.ExcelUtil;</span><br><span class="line"><span class="keyword">import</span> com.sky.course.domain.Course;</span><br><span class="line"><span class="keyword">import</span> com.sky.course.service.ICourseService;</span><br><span class="line"><span class="keyword">import</span> org.springframework.beans.factory.annotation.Autowired;</span><br><span class="line"><span class="keyword">import</span> org.springframework.security.access.prepost.PreAuthorize;</span><br><span class="line"><span class="keyword">import</span> org.springframework.web.bind.annotation.*;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> javax.servlet.http.HttpServletResponse;</span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 课程管理Controller</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span> itheima</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@RestController</span></span><br><span class="line"><span class="meta">@RequestMapping(&quot;/course/course&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">CourseController</span> <span class="keyword">extends</span> <span class="title class_">BaseController</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">private</span> ICourseService courseService;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 查询课程管理列表</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@PreAuthorize(&quot;@ss.hasPermi(&#x27;course:course:list&#x27;)&quot;)</span></span><br><span class="line">    <span class="meta">@GetMapping(&quot;/list&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> TableDataInfo <span class="title function_">list</span><span class="params">(Course course)</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="comment">//1. 开启分页</span></span><br><span class="line">        startPage();</span><br><span class="line">        <span class="comment">//2. 查询课程列表</span></span><br><span class="line">        List&lt;Course&gt; list = courseService.selectCourseList(course);</span><br><span class="line">        <span class="comment">//3. 返回表格分页数据对象</span></span><br><span class="line">        <span class="keyword">return</span> getDataTable(list);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 导出课程管理列表</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@PreAuthorize(&quot;@ss.hasPermi(&#x27;course:course:export&#x27;)&quot;)</span></span><br><span class="line">    <span class="meta">@Log(title = &quot;课程管理&quot;, businessType = BusinessType.EXPORT)</span></span><br><span class="line">    <span class="meta">@PostMapping(&quot;/export&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">export</span><span class="params">(HttpServletResponse response, Course course)</span></span><br><span class="line">    &#123;</span><br><span class="line">        List&lt;Course&gt; list = courseService.selectCourseList(course);</span><br><span class="line">        ExcelUtil&lt;Course&gt; util = <span class="keyword">new</span> <span class="title class_">ExcelUtil</span>&lt;Course&gt;(Course.class);</span><br><span class="line">        util.exportExcel(response, list, <span class="string">&quot;课程管理数据&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 获取课程管理详细信息</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@PreAuthorize(&quot;@ss.hasPermi(&#x27;course:course:query&#x27;)&quot;)</span></span><br><span class="line">    <span class="meta">@GetMapping(value = &quot;/&#123;id&#125;&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> AjaxResult <span class="title function_">getInfo</span><span class="params">(<span class="meta">@PathVariable(&quot;id&quot;)</span> Long id)</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">return</span> success(courseService.selectCourseById(id));</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 新增课程管理</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@PreAuthorize(&quot;@ss.hasPermi(&#x27;course:course:add&#x27;)&quot;)</span></span><br><span class="line">    <span class="meta">@Log(title = &quot;课程管理&quot;, businessType = BusinessType.INSERT)</span></span><br><span class="line">    <span class="meta">@PostMapping</span></span><br><span class="line">    <span class="keyword">public</span> AjaxResult <span class="title function_">add</span><span class="params">(<span class="meta">@RequestBody</span> Course course)</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">return</span> toAjax(courseService.insertCourse(course));</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 修改课程管理</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@PreAuthorize(&quot;@ss.hasPermi(&#x27;course:course:edit&#x27;)&quot;)</span></span><br><span class="line">    <span class="meta">@Log(title = &quot;课程管理&quot;, businessType = BusinessType.UPDATE)</span></span><br><span class="line">    <span class="meta">@PutMapping</span></span><br><span class="line">    <span class="keyword">public</span> AjaxResult <span class="title function_">edit</span><span class="params">(<span class="meta">@RequestBody</span> Course course)</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">return</span> toAjax(courseService.updateCourse(course));</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 删除课程管理</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@PreAuthorize(&quot;@ss.hasPermi(&#x27;course:course:remove&#x27;)&quot;)</span></span><br><span class="line">    <span class="meta">@Log(title = &quot;课程管理&quot;, businessType = BusinessType.DELETE)</span></span><br><span class="line">	<span class="meta">@DeleteMapping(&quot;/&#123;ids&#125;&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> AjaxResult <span class="title function_">remove</span><span class="params">(<span class="meta">@PathVariable</span> Long[] ids)</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">return</span> toAjax(courseService.deleteCourseByIds(ids));</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="BaseController"><a href="#BaseController" class="headerlink" title="BaseController"></a>BaseController</h3><p>Controller继承了BaseController，其中BaseController详细定义如下图：</p>
<p><img src= "" data-lazy-src="/assets/image-20240515203205623.png" alt="image-20240515203205623"> </p>
<h3 id="TableDataInfo"><a href="#TableDataInfo" class="headerlink" title="TableDataInfo"></a>TableDataInfo</h3><p>分页查询统一返回对象：表格分页数据对象</p>
<p><img src= "" data-lazy-src="/assets/image-20240515203308811.png" alt="image-20240515203308811"> </p>
<h3 id="AjaxResult"><a href="#AjaxResult" class="headerlink" title="AjaxResult"></a>AjaxResult</h3><p>增删改查统一返回对象：操作消息提醒</p>
<p><img src= "" data-lazy-src="/assets/image-20240515203414483.png" alt="image-20240515203414483"> </p>
<h3 id="BaseEntity"><a href="#BaseEntity" class="headerlink" title="BaseEntity"></a>BaseEntity</h3><p>所有实体类默认继承的BaseEntity基类</p>
<p><img src= "" data-lazy-src="/assets/image-20240515203531887.png" alt="image-20240515203531887"> </p>
<h3 id="权限注解"><a href="#权限注解" class="headerlink" title="权限注解"></a>权限注解</h3><p>@PreAuthorize 注解是 Spring Security 框架中用来做权限检查的。</p>
<p>它在运行方法前先验证权限，权限够就放行，不够就拦截。</p>
<p><img src= "" data-lazy-src="/assets/image-20240515203653598.png" alt="image-20240515203653598"> </p>
<p>权限控制流程图</p>
<p><img src= "" data-lazy-src="/assets/image-20240515203730129.png" alt="image-20240515203730129"> <img src= "" data-lazy-src="/assets/image-20240515203733871.png" alt="image-20240515203733871"> </p>
<h2 id="前后端交互流程"><a href="#前后端交互流程" class="headerlink" title="前后端交互流程"></a>前后端交互流程</h2><p>查询课程管理列表</p>
<h3 id="接口文档"><a href="#接口文档" class="headerlink" title="接口文档"></a>接口文档</h3><p><img src= "" data-lazy-src="/assets/image-20240515203815442.png" alt="image-20240515203815442"> </p>
<h3 id="跨域"><a href="#跨域" class="headerlink" title="跨域"></a>跨域</h3><p>在前端开发中，跨域是一个常见的问题，特别是在使用Vue框架进行开发时。跨域是指在浏览器中发送的AJAX请求的目标地址与当前页面的地址不在同一个域下，这会导致浏览器的同源策略产生限制，从而阻止了跨域请求的发送。然而，我们可以通过代理服务器来解决这个问题。</p>
<p><img src= "" data-lazy-src="/assets/image-20240515203903598.png" alt="image-20240515203903598"> </p>
<p>代理服务器是位于客户端和目标服务器之间的一台服务器，它接收客户端发送的请求，并将请求转发给目标服务器。通过在代理服务器上进行请求转发，可以绕过浏览器的同源策略限制，从而实现跨域请求。</p>
<p>在vue.config.js文件中添加以下内容：</p>
<p><img src= "" data-lazy-src="/assets/image-20240515203936120.png" alt="image-20240515203936120">  </p>
<h1 id="二次开发"><a href="#二次开发" class="headerlink" title="二次开发"></a>二次开发</h1><p>接下来我们将利用这些知识，实现外卖管理系统的业务功能开发，本章培养的是大家如何基于若依进行二次开发的技能，所以这里我们拿其中一个菜品管理功能给同学们进行讲解</p>
<h2 id="模块定制"><a href="#模块定制" class="headerlink" title="模块定制"></a>模块定制</h2><h3 id="若依框架修改器"><a href="#若依框架修改器" class="headerlink" title="若依框架修改器"></a>若依框架修改器</h3><p>若依框架修改器是一个可以一键修改RuoYi框架包名、项目名等的工具。</p>
<p>地址：<a target="_blank" rel="noopener" href="https://gitee.com/lpf_project/RuoYi-MT/releases">https://gitee.com/lpf_project/RuoYi-MT/releases</a></p>
<p>资料中已提供，将项目打成压缩包，直接修改即可：</p>
<p><img src= "" data-lazy-src="/assets/image-20240503154426874.png" alt="image-20240503154426874"> </p>
<p><img src= "" data-lazy-src="/assets/image-20240503154346025.png" alt="image-20240503154346025"> </p>
<h3 id="新建业务模块"><a href="#新建业务模块" class="headerlink" title="新建业务模块"></a>新建业务模块</h3><h4 id="新建子模块"><a href="#新建子模块" class="headerlink" title="新建子模块"></a>新建子模块</h4><p>在<code>sky</code>父工程下创建<code>sky-merchant</code>子模块，在<code>pom.xml</code>中导入核心模块依赖</p>
<p><img src= "" data-lazy-src="/assets/image-20240430152646977.png" alt="image-20240430152646977"> </p>
<h4 id="版本锁定"><a href="#版本锁定" class="headerlink" title="版本锁定"></a>版本锁定</h4><p>在<code>RuoYi-Vue</code>父工程<code>pom.xml</code>中进行版本锁定</p>
<p><img src= "" data-lazy-src="/assets/image-20240430152825711.png" alt="image-20240430152825711">  </p>
<h4 id="添加模块依赖"><a href="#添加模块依赖" class="headerlink" title="添加模块依赖"></a>添加模块依赖</h4><p>在<code>ruoyi-admin</code>模块<code>pom.xml</code>中添加模块依赖</p>
<p><img src= "" data-lazy-src="/assets/image-20240430152947793.png" alt="image-20240430152947793">  </p>
<h2 id="菜品管理"><a href="#菜品管理" class="headerlink" title="菜品管理"></a>菜品管理</h2><p>利用若依代码生成器（主子表模板），生成菜品管理的前后端代码。</p>
<p><img src= "" data-lazy-src="/assets/image-20240515205011305.png" alt="image-20240515205011305">  </p>
<h3 id="代码生成-2"><a href="#代码生成-2" class="headerlink" title="代码生成"></a>代码生成</h3><p>①准备SQL并导入数据库</p>
<p><img src= "" data-lazy-src="/assets/image-20240515204819091.png" alt="image-20240515204819091"> </p>
<p>②配置代码生成信息</p>
<p><img src= "" data-lazy-src="/assets/image-20240515204845464.png" alt="image-20240515204845464"> </p>
<p>③下载代码并导入项目</p>
<p><img src= "" data-lazy-src="/assets/image-20240515204901273.png" alt="image-20240515204901273"> </p>
<h3 id="升级改造"><a href="#升级改造" class="headerlink" title="升级改造"></a>升级改造</h3><h4 id="页面组件"><a href="#页面组件" class="headerlink" title="页面组件"></a>页面组件</h4><p>找到src/views/merchant/dish/index.vue文件，改造菜品查询列表和口味列表，如下：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br><span class="line">369</span><br><span class="line">370</span><br><span class="line">371</span><br><span class="line">372</span><br><span class="line">373</span><br><span class="line">374</span><br><span class="line">375</span><br><span class="line">376</span><br><span class="line">377</span><br><span class="line">378</span><br><span class="line">379</span><br><span class="line">380</span><br><span class="line">381</span><br><span class="line">382</span><br><span class="line">383</span><br><span class="line">384</span><br><span class="line">385</span><br><span class="line">386</span><br><span class="line">387</span><br><span class="line">388</span><br><span class="line">389</span><br><span class="line">390</span><br><span class="line">391</span><br><span class="line">392</span><br><span class="line">393</span><br><span class="line">394</span><br><span class="line">395</span><br><span class="line">396</span><br><span class="line">397</span><br><span class="line">398</span><br><span class="line">399</span><br><span class="line">400</span><br><span class="line">401</span><br><span class="line">402</span><br><span class="line">403</span><br><span class="line">404</span><br><span class="line">405</span><br><span class="line">406</span><br><span class="line">407</span><br><span class="line">408</span><br><span class="line">409</span><br><span class="line">410</span><br><span class="line">411</span><br><span class="line">412</span><br><span class="line">413</span><br></pre></td><td class="code"><pre><span class="line">&lt;template&gt;</span><br><span class="line">  &lt;div class=&quot;app-container&quot;&gt;</span><br><span class="line">    &lt;el-form :model=&quot;queryParams&quot; ref=&quot;queryRef&quot; :inline=&quot;true&quot; v-show=&quot;showSearch&quot; label-width=&quot;68px&quot;&gt;</span><br><span class="line">      &lt;el-form-item label=&quot;菜品名称&quot; prop=&quot;name&quot;&gt;</span><br><span class="line">        &lt;el-input</span><br><span class="line">          v-model=&quot;queryParams.name&quot;</span><br><span class="line">          placeholder=&quot;请输入菜品名称&quot;</span><br><span class="line">          clearable</span><br><span class="line">          @keyup.enter=&quot;handleQuery&quot;</span><br><span class="line">        /&gt;</span><br><span class="line">      &lt;/el-form-item&gt;</span><br><span class="line">      &lt;el-form-item label=&quot;售卖状态&quot; prop=&quot;status&quot;&gt;</span><br><span class="line">        &lt;el-select v-model=&quot;queryParams.status&quot; placeholder=&quot;请选择售卖状态&quot; clearable&gt;</span><br><span class="line">          &lt;el-option</span><br><span class="line">            v-for=&quot;dict in dish_status&quot;</span><br><span class="line">            :key=&quot;dict.value&quot;</span><br><span class="line">            :label=&quot;dict.label&quot;</span><br><span class="line">            :value=&quot;dict.value&quot;</span><br><span class="line">          /&gt;</span><br><span class="line">        &lt;/el-select&gt;</span><br><span class="line">      &lt;/el-form-item&gt;</span><br><span class="line">      &lt;el-form-item&gt;</span><br><span class="line">        &lt;el-button type=&quot;primary&quot; icon=&quot;Search&quot; @click=&quot;handleQuery&quot;&gt;搜索&lt;/el-button&gt;</span><br><span class="line">        &lt;el-button icon=&quot;Refresh&quot; @click=&quot;resetQuery&quot;&gt;重置&lt;/el-button&gt;</span><br><span class="line">      &lt;/el-form-item&gt;</span><br><span class="line">    &lt;/el-form&gt;</span><br><span class="line"></span><br><span class="line">    &lt;el-row :gutter=&quot;10&quot; class=&quot;mb8&quot;&gt;</span><br><span class="line">      &lt;el-col :span=&quot;1.5&quot;&gt;</span><br><span class="line">        &lt;el-button</span><br><span class="line">          type=&quot;primary&quot;</span><br><span class="line">          plain</span><br><span class="line">          icon=&quot;Plus&quot;</span><br><span class="line">          @click=&quot;handleAdd&quot;</span><br><span class="line">          v-hasPermi=&quot;[&#x27;merchant:dish:add&#x27;]&quot;</span><br><span class="line">        &gt;新增&lt;/el-button&gt;</span><br><span class="line">      &lt;/el-col&gt;</span><br><span class="line">      &lt;el-col :span=&quot;1.5&quot;&gt;</span><br><span class="line">        &lt;el-button</span><br><span class="line">          type=&quot;success&quot;</span><br><span class="line">          plain</span><br><span class="line">          icon=&quot;Edit&quot;</span><br><span class="line">          :disabled=&quot;single&quot;</span><br><span class="line">          @click=&quot;handleUpdate&quot;</span><br><span class="line">          v-hasPermi=&quot;[&#x27;merchant:dish:edit&#x27;]&quot;</span><br><span class="line">        &gt;修改&lt;/el-button&gt;</span><br><span class="line">      &lt;/el-col&gt;</span><br><span class="line">      &lt;el-col :span=&quot;1.5&quot;&gt;</span><br><span class="line">        &lt;el-button</span><br><span class="line">          type=&quot;danger&quot;</span><br><span class="line">          plain</span><br><span class="line">          icon=&quot;Delete&quot;</span><br><span class="line">          :disabled=&quot;multiple&quot;</span><br><span class="line">          @click=&quot;handleDelete&quot;</span><br><span class="line">          v-hasPermi=&quot;[&#x27;merchant:dish:remove&#x27;]&quot;</span><br><span class="line">        &gt;删除&lt;/el-button&gt;</span><br><span class="line">      &lt;/el-col&gt;</span><br><span class="line">      &lt;el-col :span=&quot;1.5&quot;&gt;</span><br><span class="line">        &lt;el-button</span><br><span class="line">          type=&quot;warning&quot;</span><br><span class="line">          plain</span><br><span class="line">          icon=&quot;Download&quot;</span><br><span class="line">          @click=&quot;handleExport&quot;</span><br><span class="line">          v-hasPermi=&quot;[&#x27;merchant:dish:export&#x27;]&quot;</span><br><span class="line">        &gt;导出&lt;/el-button&gt;</span><br><span class="line">      &lt;/el-col&gt;</span><br><span class="line">      &lt;right-toolbar v-model:showSearch=&quot;showSearch&quot; @queryTable=&quot;getList&quot;&gt;&lt;/right-toolbar&gt;</span><br><span class="line">    &lt;/el-row&gt;</span><br><span class="line"></span><br><span class="line">    &lt;el-table v-loading=&quot;loading&quot; :data=&quot;dishList&quot; @selection-change=&quot;handleSelectionChange&quot;&gt;</span><br><span class="line">      &lt;el-table-column type=&quot;selection&quot; width=&quot;55&quot; align=&quot;center&quot; /&gt;</span><br><span class="line">      &lt;!-- &lt;el-table-column label=&quot;主键&quot; align=&quot;center&quot; prop=&quot;id&quot; /&gt; --&gt;</span><br><span class="line">      &lt;el-table-column label=&quot;菜品名称&quot; align=&quot;center&quot; prop=&quot;name&quot; /&gt;</span><br><span class="line">      &lt;!-- &lt;el-table-column label=&quot;售价&quot; align=&quot;center&quot; prop=&quot;price&quot; /&gt; --&gt;</span><br><span class="line">      &lt;el-table-column label=&quot;售价&quot; align=&quot;center&quot;&gt;</span><br><span class="line">      &lt;template #default=&quot;&#123; row &#125;&quot;&gt;</span><br><span class="line">        &lt;span&gt;￥&#123;&#123; row.price &#125;&#125;&lt;/span&gt;</span><br><span class="line">      &lt;/template&gt;</span><br><span class="line">    &lt;/el-table-column&gt;</span><br><span class="line">      &lt;el-table-column label=&quot;图片&quot; align=&quot;center&quot; prop=&quot;image&quot; width=&quot;100&quot;&gt;</span><br><span class="line">        &lt;template #default=&quot;scope&quot;&gt;</span><br><span class="line">          &lt;image-preview :src=&quot;scope.row.image&quot; :width=&quot;50&quot; :height=&quot;50&quot;/&gt;</span><br><span class="line">        &lt;/template&gt;</span><br><span class="line">      &lt;/el-table-column&gt;</span><br><span class="line">      &lt;el-table-column label=&quot;售卖状态&quot; align=&quot;center&quot; prop=&quot;status&quot;&gt;</span><br><span class="line">        &lt;template #default=&quot;scope&quot;&gt;</span><br><span class="line">          &lt;dict-tag :options=&quot;dish_status&quot; :value=&quot;scope.row.status&quot;/&gt;</span><br><span class="line">        &lt;/template&gt;</span><br><span class="line">      &lt;/el-table-column&gt;</span><br><span class="line">      &lt;el-table-column label=&quot;更新时间&quot; align=&quot;center&quot; prop=&quot;updateTime&quot; width=&quot;180&quot;&gt;</span><br><span class="line">        &lt;template #default=&quot;scope&quot;&gt;</span><br><span class="line">         &lt;span&gt;&#123;&#123; parseTime(scope.row.updateTime, &#x27;&#123;y&#125;-&#123;m&#125;-&#123;d&#125; &#123;h&#125;:&#123;i&#125;:&#123;s&#125;&#x27;) &#125;&#125;&lt;/span&gt;</span><br><span class="line">        &lt;/template&gt;</span><br><span class="line">      &lt;/el-table-column&gt;</span><br><span class="line">      &lt;el-table-column label=&quot;操作&quot; align=&quot;center&quot; class-name=&quot;small-padding fixed-width&quot;&gt;</span><br><span class="line">        &lt;template #default=&quot;scope&quot;&gt;</span><br><span class="line">          &lt;el-button link type=&quot;primary&quot; icon=&quot;Edit&quot; @click=&quot;handleUpdate(scope.row)&quot; v-hasPermi=&quot;[&#x27;merchant:dish:edit&#x27;]&quot;&gt;修改&lt;/el-button&gt;</span><br><span class="line">          &lt;el-button link type=&quot;primary&quot; icon=&quot;Delete&quot; @click=&quot;handleDelete(scope.row)&quot; v-hasPermi=&quot;[&#x27;merchant:dish:remove&#x27;]&quot;&gt;删除&lt;/el-button&gt;</span><br><span class="line">        &lt;/template&gt;</span><br><span class="line">      &lt;/el-table-column&gt;</span><br><span class="line">    &lt;/el-table&gt;</span><br><span class="line">    </span><br><span class="line">    &lt;pagination</span><br><span class="line">      v-show=&quot;total&gt;0&quot;</span><br><span class="line">      :total=&quot;total&quot;</span><br><span class="line">      v-model:page=&quot;queryParams.pageNum&quot;</span><br><span class="line">      v-model:limit=&quot;queryParams.pageSize&quot;</span><br><span class="line">      @pagination=&quot;getList&quot;</span><br><span class="line">    /&gt;</span><br><span class="line"></span><br><span class="line">    &lt;!-- 添加或修改菜品管理对话框 --&gt;</span><br><span class="line">    &lt;el-dialog :title=&quot;title&quot; v-model=&quot;open&quot; width=&quot;600px&quot; append-to-body&gt;</span><br><span class="line">      &lt;el-form ref=&quot;dishRef&quot; :model=&quot;form&quot; :rules=&quot;rules&quot; label-width=&quot;80px&quot;&gt;</span><br><span class="line">        &lt;el-form-item label=&quot;菜品名称&quot; prop=&quot;name&quot;&gt;</span><br><span class="line">          &lt;el-input v-model=&quot;form.name&quot; placeholder=&quot;请输入菜品名称&quot; /&gt;</span><br><span class="line">        &lt;/el-form-item&gt;</span><br><span class="line">        &lt;el-form-item label=&quot;售价&quot; prop=&quot;price&quot;&gt;</span><br><span class="line">          &lt;el-input v-model=&quot;form.price&quot; placeholder=&quot;请输入售价&quot; /&gt;</span><br><span class="line">        &lt;/el-form-item&gt;</span><br><span class="line">        &lt;el-form-item label=&quot;图片&quot; prop=&quot;image&quot;&gt;</span><br><span class="line">          &lt;image-upload v-model=&quot;form.image&quot;/&gt;</span><br><span class="line">        &lt;/el-form-item&gt;</span><br><span class="line">        &lt;el-form-item label=&quot;描述信息&quot; prop=&quot;description&quot;&gt;</span><br><span class="line">          &lt;el-input v-model=&quot;form.description&quot; placeholder=&quot;请输入描述信息&quot; /&gt;</span><br><span class="line">        &lt;/el-form-item&gt;</span><br><span class="line">        &lt;el-form-item label=&quot;售卖状态&quot; prop=&quot;status&quot;&gt;</span><br><span class="line">          &lt;el-select v-model=&quot;form.status&quot; placeholder=&quot;请选择售卖状态&quot;&gt;</span><br><span class="line">            &lt;el-option</span><br><span class="line">              v-for=&quot;dict in dish_status&quot;</span><br><span class="line">              :key=&quot;dict.value&quot;</span><br><span class="line">              :label=&quot;dict.label&quot;</span><br><span class="line">              :value=&quot;parseInt(dict.value)&quot;</span><br><span class="line">            &gt;&lt;/el-option&gt;</span><br><span class="line">          &lt;/el-select&gt;</span><br><span class="line">        &lt;/el-form-item&gt;</span><br><span class="line">        &lt;el-divider content-position=&quot;center&quot;&gt;菜品口味关系信息&lt;/el-divider&gt;</span><br><span class="line">        &lt;el-row :gutter=&quot;10&quot; class=&quot;mb8&quot;&gt;</span><br><span class="line">          &lt;el-col :span=&quot;1.5&quot;&gt;</span><br><span class="line">            &lt;el-button type=&quot;primary&quot; icon=&quot;Plus&quot; @click=&quot;handleAddDishFlavor&quot;&gt;添加&lt;/el-button&gt;</span><br><span class="line">          &lt;/el-col&gt;</span><br><span class="line">          &lt;el-col :span=&quot;1.5&quot;&gt;</span><br><span class="line">            &lt;el-button type=&quot;danger&quot; icon=&quot;Delete&quot; @click=&quot;handleDeleteDishFlavor&quot;&gt;删除&lt;/el-button&gt;</span><br><span class="line">          &lt;/el-col&gt;</span><br><span class="line">        &lt;/el-row&gt;</span><br><span class="line">        &lt;el-table :data=&quot;dishFlavorList&quot; :row-class-name=&quot;rowDishFlavorIndex&quot; @selection-change=&quot;handleDishFlavorSelectionChange&quot; ref=&quot;dishFlavor&quot;&gt;</span><br><span class="line">          &lt;el-table-column type=&quot;selection&quot; width=&quot;50&quot; align=&quot;center&quot; /&gt;</span><br><span class="line">          &lt;el-table-column label=&quot;序号&quot; align=&quot;center&quot; prop=&quot;index&quot; width=&quot;50&quot;/&gt;</span><br><span class="line">          &lt;el-table-column label=&quot;口味名称&quot; prop=&quot;name&quot; width=&quot;150&quot;&gt;</span><br><span class="line">            &lt;template #default=&quot;scope&quot;&gt;</span><br><span class="line">              &lt;!-- &lt;el-input v-model=&quot;scope.row.name&quot; placeholder=&quot;请输入口味名称&quot; /&gt; --&gt;</span><br><span class="line">              &lt;el-select v-model=&quot;scope.row.name&quot; placeholder=&quot;请选择口味名称&quot;</span><br><span class="line">              @change=&quot;changeFlavorName(scope.row)&quot; &gt;</span><br><span class="line">                &lt;el-option</span><br><span class="line">                  v-for=&quot;dishFlavor in dishFlavorListSelect&quot;</span><br><span class="line">                  :key=&quot;dishFlavor.name&quot;</span><br><span class="line">                  :label=&quot;dishFlavor.name&quot;</span><br><span class="line">                  :value=&quot;dishFlavor.name&quot;</span><br><span class="line">                /&gt;</span><br><span class="line">              &lt;/el-select&gt;</span><br><span class="line">            &lt;/template&gt;</span><br><span class="line">          &lt;/el-table-column&gt;</span><br><span class="line">          &lt;el-table-column label=&quot;口味列表&quot; prop=&quot;value&quot; width=&quot;350&quot;&gt;</span><br><span class="line">            &lt;template #default=&quot;scope&quot;&gt;</span><br><span class="line">              &lt;!-- &lt;el-input v-model=&quot;scope.row.value&quot; placeholder=&quot;请输入口味列表&quot; /&gt; --&gt;</span><br><span class="line">              &lt;el-select v-model=&quot;scope.row.value&quot; placeholder=&quot;请选择口味列表&quot; multiple</span><br><span class="line">              @focus=&quot;focusFlavorName(scope.row)&quot; style=&quot;width: 90%;&quot;&gt;</span><br><span class="line">                &lt;el-option</span><br><span class="line">                  v-for=&quot;value in checkValueList&quot;</span><br><span class="line">                  :key=&quot;value&quot;</span><br><span class="line">                  :label=&quot;value&quot;</span><br><span class="line">                  :value=&quot;value&quot;</span><br><span class="line">                /&gt;</span><br><span class="line">              &lt;/el-select&gt;</span><br><span class="line">            &lt;/template&gt;</span><br><span class="line">          &lt;/el-table-column&gt;</span><br><span class="line">        &lt;/el-table&gt;</span><br><span class="line">      &lt;/el-form&gt;</span><br><span class="line">      &lt;template #footer&gt;</span><br><span class="line">        &lt;div class=&quot;dialog-footer&quot;&gt;</span><br><span class="line">          &lt;el-button type=&quot;primary&quot; @click=&quot;submitForm&quot;&gt;确 定&lt;/el-button&gt;</span><br><span class="line">          &lt;el-button @click=&quot;cancel&quot;&gt;取 消&lt;/el-button&gt;</span><br><span class="line">        &lt;/div&gt;</span><br><span class="line">      &lt;/template&gt;</span><br><span class="line">    &lt;/el-dialog&gt;</span><br><span class="line">  &lt;/div&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;script setup name=&quot;Dish&quot;&gt;</span><br><span class="line">import &#123; listDish, getDish, delDish, addDish, updateDish &#125; from &quot;@/api/merchant/dish&quot;;</span><br><span class="line">import &#123; ref &#125; from &quot;vue&quot;;</span><br><span class="line"></span><br><span class="line">const &#123; proxy &#125; = getCurrentInstance();</span><br><span class="line">const &#123; dish_status &#125; = proxy.useDict(&#x27;dish_status&#x27;);</span><br><span class="line"></span><br><span class="line">const dishList = ref([]);</span><br><span class="line">const dishFlavorList = ref([]);</span><br><span class="line">const open = ref(false);</span><br><span class="line">const loading = ref(true);</span><br><span class="line">const showSearch = ref(true);</span><br><span class="line">const ids = ref([]);</span><br><span class="line">const checkedDishFlavor = ref([]);</span><br><span class="line">const single = ref(true);</span><br><span class="line">const multiple = ref(true);</span><br><span class="line">const total = ref(0);</span><br><span class="line">const title = ref(&quot;&quot;);</span><br><span class="line"></span><br><span class="line">const data = reactive(&#123;</span><br><span class="line">  form: &#123;&#125;,</span><br><span class="line">  queryParams: &#123;</span><br><span class="line">    pageNum: 1,</span><br><span class="line">    pageSize: 10,</span><br><span class="line">    name: null,</span><br><span class="line">    status: null,</span><br><span class="line">  &#125;,</span><br><span class="line">  rules: &#123;</span><br><span class="line">    name: [</span><br><span class="line">      &#123; required: true, message: &quot;菜品名称不能为空&quot;, trigger: &quot;blur&quot; &#125;</span><br><span class="line">    ],</span><br><span class="line">    price: [</span><br><span class="line">      &#123; required: true, message: &quot;售价不能为空&quot;, trigger: &quot;blur&quot; &#125;</span><br><span class="line">    ],</span><br><span class="line">    image: [</span><br><span class="line">      &#123; required: true, message: &quot;图片不能为空&quot;, trigger: &quot;blur&quot; &#125;</span><br><span class="line">    ],</span><br><span class="line">    status: [</span><br><span class="line">      &#123; required: true, message: &quot;售卖状态不能为空&quot;, trigger: &quot;change&quot; &#125;</span><br><span class="line">    ],</span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">const &#123; queryParams, form, rules &#125; = toRefs(data);</span><br><span class="line">//-----------------------------</span><br><span class="line">// 定义口味名称和口味列表静态数据</span><br><span class="line">const dishFlavorListSelect=ref([</span><br><span class="line">  &#123;name:&quot;辣度&quot;,value:[&quot;不辣&quot;,&quot;微辣&quot;,&quot;中辣&quot;,&quot;重辣&quot;]&#125;,</span><br><span class="line">  &#123;name:&quot;忌口&quot;,value:[&quot;不要葱&quot;,&quot;不要蒜&quot;,&quot;不要香菜&quot;,&quot;不要辣&quot;]&#125;,</span><br><span class="line">  &#123;name:&quot;甜味&quot;,value:[&quot;无糖&quot;,&quot;少糖&quot;,&quot;半糖&quot;,&quot;多糖&quot;]&#125;</span><br><span class="line">]);</span><br><span class="line">// 存储当前选中口味列表数组</span><br><span class="line">const checkValueList=ref([]);</span><br><span class="line">// 定义改变口味名称时更新当前选中的口味列表</span><br><span class="line">function changeFlavorName(row)&#123;</span><br><span class="line">  // 清空当前行value</span><br><span class="line">  row.value=[];</span><br><span class="line">  // 根据选中name去查找静态数据的value</span><br><span class="line">  checkValueList.value=dishFlavorListSelect.value.find(item=&gt;item.name==row.name).value;</span><br><span class="line">&#125;</span><br><span class="line">// 定义口味列表获取焦点时更新当前选中的口味列表</span><br><span class="line">function focusFlavorName(row)&#123;</span><br><span class="line">  // 根据选中name去查找静态数据的value</span><br><span class="line">  checkValueList.value=dishFlavorListSelect.value.find(item=&gt;item.name==row.name).value;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">//-----------------------------</span><br><span class="line">/** 查询菜品管理列表 */</span><br><span class="line">function getList() &#123;</span><br><span class="line">  loading.value = true;</span><br><span class="line">  listDish(queryParams.value).then(response =&gt; &#123;</span><br><span class="line">    dishList.value = response.rows;</span><br><span class="line">    total.value = response.total;</span><br><span class="line">    loading.value = false;</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">// 取消按钮</span><br><span class="line">function cancel() &#123;</span><br><span class="line">  open.value = false;</span><br><span class="line">  reset();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">// 表单重置</span><br><span class="line">function reset() &#123;</span><br><span class="line">  form.value = &#123;</span><br><span class="line">    id: null,</span><br><span class="line">    name: null,</span><br><span class="line">    price: null,</span><br><span class="line">    image: null,</span><br><span class="line">    description: null,</span><br><span class="line">    status: null,</span><br><span class="line">    createTime: null,</span><br><span class="line">    updateTime: null</span><br><span class="line">  &#125;;</span><br><span class="line">  dishFlavorList.value = [];</span><br><span class="line">  proxy.resetForm(&quot;dishRef&quot;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">/** 搜索按钮操作 */</span><br><span class="line">function handleQuery() &#123;</span><br><span class="line">  queryParams.value.pageNum = 1;</span><br><span class="line">  getList();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">/** 重置按钮操作 */</span><br><span class="line">function resetQuery() &#123;</span><br><span class="line">  proxy.resetForm(&quot;queryRef&quot;);</span><br><span class="line">  handleQuery();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">// 多选框选中数据</span><br><span class="line">function handleSelectionChange(selection) &#123;</span><br><span class="line">  ids.value = selection.map(item =&gt; item.id);</span><br><span class="line">  single.value = selection.length != 1;</span><br><span class="line">  multiple.value = !selection.length;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">/** 新增按钮操作 */</span><br><span class="line">function handleAdd() &#123;</span><br><span class="line">  reset();</span><br><span class="line">  open.value = true;</span><br><span class="line">  title.value = &quot;添加菜品管理&quot;;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">/** 修改按钮操作 */</span><br><span class="line">function handleUpdate(row) &#123;</span><br><span class="line">  reset();</span><br><span class="line">  const _id = row.id || ids.value</span><br><span class="line">  getDish(_id).then(response =&gt; &#123;</span><br><span class="line">    form.value = response.data;</span><br><span class="line">    dishFlavorList.value = response.data.dishFlavorList;</span><br><span class="line">    // 将口味列表value字符串转为json数组</span><br><span class="line">    if(dishFlavorList.value!=null)&#123;</span><br><span class="line">      dishFlavorList.value.forEach(item =&gt; &#123;</span><br><span class="line">      item.value = JSON.parse(item.value);</span><br><span class="line">    &#125;);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    open.value = true;</span><br><span class="line">    title.value = &quot;修改菜品管理&quot;;</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">/** 提交按钮 */</span><br><span class="line">function submitForm() &#123;</span><br><span class="line">  proxy.$refs[&quot;dishRef&quot;].validate(valid =&gt; &#123;</span><br><span class="line">    if (valid) &#123;</span><br><span class="line">      form.value.dishFlavorList = dishFlavorList.value;</span><br><span class="line">      // 将口味列表中value通过JSON工具类转为字符串</span><br><span class="line">      if(form.value.dishFlavorList!=null)&#123;</span><br><span class="line">        form.value.dishFlavorList.forEach(item=&gt;&#123;</span><br><span class="line">        item.value = JSON.stringify(item.value)</span><br><span class="line">      &#125;)</span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">    </span><br><span class="line">      if (form.value.id != null) &#123;</span><br><span class="line">        updateDish(form.value).then(response =&gt; &#123;</span><br><span class="line">          proxy.$modal.msgSuccess(&quot;修改成功&quot;);</span><br><span class="line">          open.value = false;</span><br><span class="line">          getList();</span><br><span class="line">        &#125;);</span><br><span class="line">      &#125; else &#123;</span><br><span class="line">        addDish(form.value).then(response =&gt; &#123;</span><br><span class="line">          proxy.$modal.msgSuccess(&quot;新增成功&quot;);</span><br><span class="line">          open.value = false;</span><br><span class="line">          getList();</span><br><span class="line">        &#125;);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">/** 删除按钮操作 */</span><br><span class="line">function handleDelete(row) &#123;</span><br><span class="line">  const _ids = row.id || ids.value;</span><br><span class="line">  proxy.$modal.confirm(&#x27;是否确认删除菜品管理编号为&quot;&#x27; + _ids + &#x27;&quot;的数据项？&#x27;).then(function() &#123;</span><br><span class="line">    return delDish(_ids);</span><br><span class="line">  &#125;).then(() =&gt; &#123;</span><br><span class="line">    getList();</span><br><span class="line">    proxy.$modal.msgSuccess(&quot;删除成功&quot;);</span><br><span class="line">  &#125;).catch(() =&gt; &#123;&#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">/** 菜品口味关系序号 */</span><br><span class="line">function rowDishFlavorIndex(&#123; row, rowIndex &#125;) &#123;</span><br><span class="line">  row.index = rowIndex + 1;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">/** 菜品口味关系添加按钮操作 */</span><br><span class="line">function handleAddDishFlavor() &#123;</span><br><span class="line">  let obj = &#123;&#125;;</span><br><span class="line">  obj.name = &quot;&quot;;</span><br><span class="line">  obj.value = &quot;&quot;;</span><br><span class="line">  dishFlavorList.value.push(obj);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">/** 菜品口味关系删除按钮操作 */</span><br><span class="line">function handleDeleteDishFlavor() &#123;</span><br><span class="line">  if (checkedDishFlavor.value.length == 0) &#123;</span><br><span class="line">    proxy.$modal.msgError(&quot;请先选择要删除的菜品口味关系数据&quot;);</span><br><span class="line">  &#125; else &#123;</span><br><span class="line">    const dishFlavors = dishFlavorList.value;</span><br><span class="line">    const checkedDishFlavors = checkedDishFlavor.value;</span><br><span class="line">    dishFlavorList.value = dishFlavors.filter(function(item) &#123;</span><br><span class="line">      return checkedDishFlavors.indexOf(item.index) == -1</span><br><span class="line">    &#125;);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">/** 复选框选中数据 */</span><br><span class="line">function handleDishFlavorSelectionChange(selection) &#123;</span><br><span class="line">  checkedDishFlavor.value = selection.map(item =&gt; item.index)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">/** 导出按钮操作 */</span><br><span class="line">function handleExport() &#123;</span><br><span class="line">  proxy.download(&#x27;merchant/dish/export&#x27;, &#123;</span><br><span class="line">    ...queryParams.value</span><br><span class="line">  &#125;, `dish_$&#123;new Date().getTime()&#125;.xlsx`)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">getList();</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>
<h4 id="图片上传组件"><a href="#图片上传组件" class="headerlink" title="图片上传组件"></a>图片上传组件</h4><p>由于之前的图片访问是本地的路径和服务，需要发起请求才能获取图片，现在我们使用了OSS，图片可直接访问，无需再次访问后端服务，所以前端的图片访问逻辑我们需要修改</p>
<ul>
<li>修改文件位置：src/components/imageUpload/index.vue</li>
<li>如果图片路径是以http开头的，则不走后台服务访问，直接访问OSS，之前的不变，如下图</li>
</ul>
<p><img src= "" data-lazy-src="/assets/image-20240515205705604.png" alt="image-20240515205705604"> </p>
<h2 id="页面调整"><a href="#页面调整" class="headerlink" title="页面调整"></a>页面调整</h2><p>如果使用若依框架项目做为脚手架，那么我们肯定需要在页面显示中，符合自己公司或者项目的标识才行，需要更换的地方很多，我们依次来解决它</p>
<ul>
<li>浏览器标签页logo标识、标题</li>
<li>系统页面中的logo标识、标题</li>
<li>去除源码地址 &amp; 文档地址</li>
<li>主题风格和菜单图标</li>
<li>登录名称及背景图</li>
</ul>
<p><img src= "" data-lazy-src="/assets/image-20240515211842252.png" alt="image-20240515211842252">   </p>
<p><img src= "" data-lazy-src="/assets/image-20240515211848147.png" alt="image-20240515211848147"> </p>
<h3 id="浏览器标签页icon、标题"><a href="#浏览器标签页icon、标题" class="headerlink" title="浏览器标签页icon、标题"></a>浏览器标签页icon、标题</h3><p>找到资料中的logo图标，替换前端项目中的public文件夹，删除原有的favicon.ico，把新拷贝过来的logo更名为favicon.ico即可</p>
<p><img src= "" data-lazy-src="/assets/image-20240503154918697.png" alt="image-20240503154918697"> </p>
<p>找到根目录下的index.html文件，把title更换为自己想要的内容即可</p>
<p><img src= "" data-lazy-src="/assets/image-20240503154945668.png" alt="image-20240503154945668"> </p>
<h3 id="系统页面中的logo、标题"><a href="#系统页面中的logo、标题" class="headerlink" title="系统页面中的logo、标题"></a>系统页面中的logo、标题</h3><p>找到资料中的logo文件，替换 src//assets/logo/logo.png文件</p>
<p><img src= "" data-lazy-src="/assets/image-20240503155059313.png" alt="image-20240503155059313"> </p>
<p>若依的系统页面标题引用的是开发环境的配置，我们只需要修改开发的环境的VITE_APP_TITLE属性即可</p>
<p><img src= "" data-lazy-src="/assets/image-20240503155126721.png" alt="image-20240503155126721"> </p>
<h3 id="去除源码-amp-文档"><a href="#去除源码-amp-文档" class="headerlink" title="去除源码 &amp; 文档"></a>去除源码 &amp; 文档</h3><p><img src= "" data-lazy-src="/assets/image-20240503155305048.png" alt="image-20240503155305048"> </p>
<h3 id="主题和自定义图标"><a href="#主题和自定义图标" class="headerlink" title="主题和自定义图标"></a>主题和自定义图标</h3><p>在目前的前端项目中，已经提供了非常便利的操作方式，可以切换主题的风格</p>
<p>操作：点击右上角的头像，可以找到<strong>布局设置，</strong>如下操作</p>
<p><img src= "" data-lazy-src="/assets/17157783775591.png" alt="img"> </p>
<p>在前端代码中也有对应的操作，更好主题风格文件位置：src/setting.js</p>
<p><img src= "" data-lazy-src="/assets/image-20240515210823709.png" alt="image-20240515210823709"> </p>
<p>更换主题颜色文件位置：src/store/modules/settings.js</p>
<p><img src= "" data-lazy-src="/assets/image-20240515210930466.png" alt="image-20240515210930466"> </p>
<p>访问阿里巴巴矢量图库，搜索图标：<a target="_blank" rel="noopener" href="https://www.iconfont.cn/search/index?searchType=icon&amp;q=%E8%8F%9C%E5%93%81%E7%AE%A1%E7%90%86">https://www.iconfont.cn/search/index?searchType=icon&amp;q=%E8%8F%9C%E5%93%81%E7%AE%A1%E7%90%86</a></p>
<p><img src= "" data-lazy-src="/assets/image-20240515211041187.png" alt="image-20240515211041187"> </p>
<p>将下载好的图标复制到src//assets/icons/svg目录下，就可以给指定菜单设置图标了</p>
<p><img src= "" data-lazy-src="/assets/image-20240503155635595.png" alt="image-20240503155635595"> </p>
<h3 id="登录页面中标题、背景图"><a href="#登录页面中标题、背景图" class="headerlink" title="登录页面中标题、背景图"></a>登录页面中标题、背景图</h3><p>登录名称和背景图，我们可以直接找到登录的组件进行修改即可</p>
<p>组件位置：src/views/login.vue</p>
<p><img src= "" data-lazy-src="/assets/image-20240510110514167.png" alt="image-20240510110514167"> </p>
<p><img src= "" data-lazy-src="/assets/image-20240503155545404.png" alt="image-20240503155545404"> </p>
</article><div class="post-copyright"><div class="post-copyright__title"><span class="post-copyright-info"><h>若依框架</h></span></div><div class="post-copyright__type"><span class="post-copyright-info"><a href="https://srs-blog.github.io/2025/04/13/若依基础应用篇/">https://srs-blog.github.io/2025/04/13/若依基础应用篇/</a></span></div><div class="post-copyright-m"><div class="post-copyright-m-info"><div class="post-copyright-a"><h>作者</h><div class="post-copyright-cc-info"><h>SRS</h></div></div><div class="post-copyright-c"><h>发布于</h><div class="post-copyright-cc-info"><h>2025-04-13</h></div></div><div class="post-copyright-u"><h>更新于</h><div class="post-copyright-cc-info"><h>2025-04-13</h></div></div><div class="post-copyright-c"><h>许可协议</h><div class="post-copyright-cc-info"><a class="icon" rel="noopener" target="_blank" title="Creative Commons" href="https://creativecommons.org/"><i class="fab fa-creative-commons"></i></a><a rel="noopener" target="_blank" title="CC BY-NC-SA 4.0" href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY-NC-SA 4.0</a></div></div></div></div></div><div class="tag_share"><div class="post-share"><div class="social-share" data-image="/img/bac-1.jpg" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/js/social-share.min.js" defer></script></div></div><link rel="stylesheet" href="/css/coin.css" media="defer" onload="this.media='all'"/><div class="post-reward"><button class="tip-button reward-button"><span class="tip-button__text">不给糖就捣蛋</span><div class="coin-wrapper"><div class="coin"><div class="coin__middle"></div><div class="coin__back"></div><div class="coin__front"></div></div></div><div class="reward-main"><ul class="reward-all"><li class="reward-item"><a href="/img/skm.jpg" target="_blank"><img class="post-qr-code-img" src= "" data-lazy-src="/img/skm.jpg" alt="wechat"/></a><div class="post-qr-code-desc">wechat</div></li></ul></div></button></div><audio id="coinAudio" src="https://cdn.cbd.int/akilar-candyassets@1.0.36/audio/aowu.m4a"></audio><script defer="defer" src="/js/coin.js"></script><nav class="pagination-post" id="pagination"><a class="pagination-related full-width" href="/2025/04/11/%E5%A4%9A%E7%BA%BF%E7%A8%8B/" title="多线程"><img class="cover" src= "" data-lazy-src="/img/bac-7.jpg" onerror="onerror=null;src='/img/404.jpg'" alt="cover of previous post"><div class="info"><div class="info-1"><div class="info-item-1">上一篇</div><div class="info-item-2">多线程</div></div><div class="info-2"><div class="info-item-1">1.实现多线程1.1简单了解多线程【理解】是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多个线程，提升性能。  1.2并发和并行【理解】 并行：在同一时刻，有多个指令在多个CPU上同时执行。   并发：在同一时刻，有多个指令在单个CPU上交替执行。    1.3进程和线程【理解】 进程：是正在运行的程序 独立性：进程是一个能独立运行的基本单位，同时也是系统分配资源和调度的独立单位动态性：进程的实质是程序的一次执行过程，进程是动态产生，动态消亡的并发性：任何进程都可以同其他进程一起并发执行  线程：是进程中的单个顺序控制流，是一条执行路径 ​    单线程：一个进程如果只有一条执行路径，则称为单线程程序 ​    多线程：一个进程如果有多条执行路径，则称为多线程程序 ​       1.4实现多线程方式一：继承Thread类【应用】  方法介绍 | 方法名          | 说明                         || —————— | ————————————— || void run()   |...</div></div></div></a></nav><hr class="custom-hr"/><div id="post-comment"><div class="comment-head"><div class="comment-headline"><i class="fas fa-comments fa-fw"></i><span> 评论</span></div></div><div class="comment-wrap"><div><div id="twikoo-wrap"></div></div></div></div></div><div class="aside-content" id="aside-content"><div class="card-widget card-info text-center"><div class="author_top is-center"> </div><div class="card-info-avatar"><div class="avatar-img"><img src= "" data-lazy-src="/img/srs.jpg" onerror="this.onerror=null;this.src='/img/friend_404.gif'" alt="avatar"/></div><div class="author-status-box"><div class="author-status"><g-emoji class="g-emoji" alias="palm_tree" fallback-src="https://lskypro.acozycotage.net/LightPicture/2022/12/fe1dc0402e623096.jpg">🐟</g-emoji><span>认真摸鱼中</span></div></div></div><div class="author-info-name">SRS</div><div class="author-info-description">SRS的个人博客</div><div class="site-data"><a href="/archives/"><div class="headline">文章</div><div class="length-num">9</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">0</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">4</div></a></div><a id="card-info-btn" target="_blank" rel="noopener" href="https://github.com/SRS-Blog"><i></i><span>前往小窝<i class="faa-passing animated" style="padding-left:20px;display:inline-block;vertical-align:middle;"><svg class="icon" style="height:28px;width:28px;fill:currentColor;position:relative;top:5px"><use xlink:href="#icon-xiaoqiche"></use></svg></i></span></a><div class="card-info-social-icons"><a class="social-icon faa-parent animated-hover" href="https://github.com/SRS-Blog" target="_blank" title="Github"><svg class="social_icon faa-tada" aria-hidden="true"><use xlink:href="#icon-github"></use></svg></a><a class="social-icon faa-parent animated-hover" href="mailto:SRS15303449212@163.com" target="_blank" title="邮件"><svg class="social_icon faa-tada" aria-hidden="true"><use xlink:href="#icon-mail"></use></svg></a><a class="social-icon faa-parent animated-hover" href="/img/wechat.jpg" target="_blank" title="微信"><svg class="social_icon faa-tada" aria-hidden="true"><use xlink:href="#icon-weixinmendian"></use></svg></a><a class="social-icon faa-parent animated-hover" href="https://res.abeim.cn/api/qq/?qq=1440761261" target="_blank" title="QQ"><svg class="social_icon faa-tada" aria-hidden="true"><use xlink:href="#icon-QQ"></use></svg></a></div></div><div class="card-widget card-announcement"><div class="item-headline"><a class="faa-parent animated-hover"><svg class="faa-tada icon" style="height:30px;width:25px;fill:currentColor;position:relative;top:5px" aria-hidden="true"><use href="#icon-gonggao1"></use></svg></a><span>公告栏</span></div><div class="announcement_content"></div><div id="welcome-info"></div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#%E8%8B%A5%E4%BE%9D%E6%90%AD%E5%BB%BA"><span class="toc-text">若依搭建</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%8B%A5%E4%BE%9D%E7%89%88%E6%9C%AC"><span class="toc-text">若依版本</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AE%98%E6%96%B9"><span class="toc-text">官方</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%9D%9E%E5%AE%98%E6%96%B9"><span class="toc-text">非官方</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#RuoYi-Vue"><span class="toc-text">RuoYi-Vue</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%BF%90%E8%A1%8C%E5%90%8E%E7%AB%AF%E9%A1%B9%E7%9B%AE"><span class="toc-text">运行后端项目</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%88%9D%E5%A7%8B%E5%8C%96%E9%A1%B9%E7%9B%AE"><span class="toc-text">初始化项目</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#Git%E4%B8%8B%E8%BD%BD"><span class="toc-text">Git下载</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Maven%E6%9E%84%E5%BB%BA"><span class="toc-text">Maven构建</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#MySQL%E7%9B%B8%E5%85%B3"><span class="toc-text">MySQL相关</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%AF%BC%E5%85%A5sql"><span class="toc-text">导入sql</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E9%85%8D%E7%BD%AE%E4%BF%A1%E6%81%AF"><span class="toc-text">配置信息</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Redis%E7%9B%B8%E5%85%B3"><span class="toc-text">Redis相关</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%90%AF%E5%8A%A8"><span class="toc-text">启动</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E9%85%8D%E7%BD%AE%E4%BF%A1%E6%81%AF-1"><span class="toc-text">配置信息</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%A1%B9%E7%9B%AE%E8%BF%90%E8%A1%8C"><span class="toc-text">项目运行</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%BF%90%E8%A1%8C%E5%89%8D%E7%AB%AF%E9%A1%B9%E7%9B%AE"><span class="toc-text">运行前端项目</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%88%9D%E5%A7%8B%E5%8C%96%E9%A1%B9%E7%9B%AE-1"><span class="toc-text">初始化项目</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%A1%B9%E7%9B%AE%E8%BF%90%E8%A1%8C-1"><span class="toc-text">项目运行</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%85%A5%E9%97%A8%E6%A1%88%E4%BE%8B"><span class="toc-text">入门案例</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%8A%9F%E8%83%BD%E9%9C%80%E6%B1%82"><span class="toc-text">功能需求</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%AD%A5%E9%AA%A4%E5%88%86%E6%9E%90"><span class="toc-text">步骤分析</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BB%A3%E7%A0%81%E7%94%9F%E6%88%90"><span class="toc-text">代码生成</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%8F%90%E4%BE%9B%E8%AF%BE%E7%A8%8B%E8%A1%A8"><span class="toc-text">提供课程表</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%B3%BB%E7%BB%9F%E5%AF%BC%E5%85%A5"><span class="toc-text">系统导入</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%85%8D%E7%BD%AE%E4%BB%A3%E7%A0%81"><span class="toc-text">配置代码</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%82%B9%E5%87%BB%E7%94%9F%E6%88%90"><span class="toc-text">点击生成</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BB%A3%E7%A0%81%E5%AF%BC%E5%85%A5"><span class="toc-text">代码导入</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AF%BC%E5%85%A5%E8%AF%BE%E7%A8%8B%E8%8F%9C%E5%8D%95"><span class="toc-text">导入课程菜单</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AF%BC%E5%85%A5%E5%90%8E%E7%AB%AF%E4%BB%A3%E7%A0%81"><span class="toc-text">导入后端代码</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AF%BC%E5%85%A5%E5%89%8D%E7%AB%AF%E4%BB%A3%E7%A0%81"><span class="toc-text">导入前端代码</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%AE%BF%E9%97%AE%E6%B5%8B%E8%AF%95"><span class="toc-text">访问测试</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%8A%9F%E8%83%BD%E8%AF%A6%E8%A7%A3"><span class="toc-text">功能详解</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%B3%BB%E7%BB%9F%E7%AE%A1%E7%90%86"><span class="toc-text">系统管理</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%9D%83%E9%99%90%E7%B3%BB%E7%BB%9F"><span class="toc-text">权限系统</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%BC%94%E7%A4%BA"><span class="toc-text">演示</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#RBAC"><span class="toc-text">RBAC</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E8%A1%A8%E5%85%B3%E7%B3%BB"><span class="toc-text">表关系</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%A1%88%E4%BE%8B"><span class="toc-text">案例</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%95%B0%E6%8D%AE%E5%AD%97%E5%85%B8"><span class="toc-text">数据字典</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BB%8B%E7%BB%8D"><span class="toc-text">介绍</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E8%A1%A8%E5%85%B3%E7%B3%BB-1"><span class="toc-text">表关系</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%A1%88%E4%BE%8B-1"><span class="toc-text">案例</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%8F%82%E6%95%B0%E8%AE%BE%E7%BD%AE"><span class="toc-text">参数设置</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%80%9A%E7%9F%A5%E5%85%AC%E5%91%8A"><span class="toc-text">通知公告</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%97%A5%E5%BF%97%E7%AE%A1%E7%90%86"><span class="toc-text">日志管理</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%B3%BB%E7%BB%9F%E7%9B%91%E6%8E%A7"><span class="toc-text">系统监控</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%9B%91%E6%8E%A7%E7%9B%B8%E5%85%B3"><span class="toc-text">监控相关</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1"><span class="toc-text">定时任务</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BB%8B%E7%BB%8D-1"><span class="toc-text">介绍</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%A1%88%E4%BE%8B-2"><span class="toc-text">案例</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%B3%BB%E7%BB%9F%E5%B7%A5%E5%85%B7"><span class="toc-text">系统工具</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%A1%A8%E5%8D%95%E6%9E%84%E5%BB%BA"><span class="toc-text">表单构建</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BB%8B%E7%BB%8D-2"><span class="toc-text">介绍</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%A1%88%E4%BE%8B-3"><span class="toc-text">案例</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BB%A3%E7%A0%81%E7%94%9F%E6%88%90-1"><span class="toc-text">代码生成</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%B3%BB%E7%BB%9F%E6%8E%A5%E5%8F%A3"><span class="toc-text">系统接口</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E9%A1%B9%E7%9B%AE%E7%BB%93%E6%9E%84"><span class="toc-text">项目结构</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%90%8E%E7%AB%AF%E7%BB%93%E6%9E%84"><span class="toc-text">后端结构</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E9%A1%B9%E7%9B%AE%E4%B8%AD%E9%85%8D%E7%BD%AE"><span class="toc-text">项目中配置</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%A8%A1%E5%9D%97%E4%BE%9D%E8%B5%96%E5%85%B3%E7%B3%BB"><span class="toc-text">模块依赖关系</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%89%8D%E7%AB%AF%E7%BB%93%E6%9E%84"><span class="toc-text">前端结构</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%A1%A8%E7%BB%93%E6%9E%84%E4%BB%8B%E7%BB%8D"><span class="toc-text">表结构介绍</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E6%BA%90%E7%A0%81%E9%98%85%E8%AF%BB"><span class="toc-text">源码阅读</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%89%8D%E7%AB%AF%E4%BB%A3%E7%A0%81%E5%88%86%E6%9E%90"><span class="toc-text">前端代码分析</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%90%8E%E7%AB%AF%E4%BB%A3%E7%A0%81%E5%88%86%E6%9E%90"><span class="toc-text">后端代码分析</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#CourseController"><span class="toc-text">CourseController</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#BaseController"><span class="toc-text">BaseController</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#TableDataInfo"><span class="toc-text">TableDataInfo</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#AjaxResult"><span class="toc-text">AjaxResult</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#BaseEntity"><span class="toc-text">BaseEntity</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%9D%83%E9%99%90%E6%B3%A8%E8%A7%A3"><span class="toc-text">权限注解</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%89%8D%E5%90%8E%E7%AB%AF%E4%BA%A4%E4%BA%92%E6%B5%81%E7%A8%8B"><span class="toc-text">前后端交互流程</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%8E%A5%E5%8F%A3%E6%96%87%E6%A1%A3"><span class="toc-text">接口文档</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%B7%A8%E5%9F%9F"><span class="toc-text">跨域</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E4%BA%8C%E6%AC%A1%E5%BC%80%E5%8F%91"><span class="toc-text">二次开发</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%A8%A1%E5%9D%97%E5%AE%9A%E5%88%B6"><span class="toc-text">模块定制</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%8B%A5%E4%BE%9D%E6%A1%86%E6%9E%B6%E4%BF%AE%E6%94%B9%E5%99%A8"><span class="toc-text">若依框架修改器</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%96%B0%E5%BB%BA%E4%B8%9A%E5%8A%A1%E6%A8%A1%E5%9D%97"><span class="toc-text">新建业务模块</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%96%B0%E5%BB%BA%E5%AD%90%E6%A8%A1%E5%9D%97"><span class="toc-text">新建子模块</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%89%88%E6%9C%AC%E9%94%81%E5%AE%9A"><span class="toc-text">版本锁定</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%B7%BB%E5%8A%A0%E6%A8%A1%E5%9D%97%E4%BE%9D%E8%B5%96"><span class="toc-text">添加模块依赖</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%8F%9C%E5%93%81%E7%AE%A1%E7%90%86"><span class="toc-text">菜品管理</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BB%A3%E7%A0%81%E7%94%9F%E6%88%90-2"><span class="toc-text">代码生成</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%8D%87%E7%BA%A7%E6%94%B9%E9%80%A0"><span class="toc-text">升级改造</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E9%A1%B5%E9%9D%A2%E7%BB%84%E4%BB%B6"><span class="toc-text">页面组件</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%9B%BE%E7%89%87%E4%B8%8A%E4%BC%A0%E7%BB%84%E4%BB%B6"><span class="toc-text">图片上传组件</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E9%A1%B5%E9%9D%A2%E8%B0%83%E6%95%B4"><span class="toc-text">页面调整</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%B5%8F%E8%A7%88%E5%99%A8%E6%A0%87%E7%AD%BE%E9%A1%B5icon%E3%80%81%E6%A0%87%E9%A2%98"><span class="toc-text">浏览器标签页icon、标题</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%B3%BB%E7%BB%9F%E9%A1%B5%E9%9D%A2%E4%B8%AD%E7%9A%84logo%E3%80%81%E6%A0%87%E9%A2%98"><span class="toc-text">系统页面中的logo、标题</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%8E%BB%E9%99%A4%E6%BA%90%E7%A0%81-amp-%E6%96%87%E6%A1%A3"><span class="toc-text">去除源码 &amp; 文档</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%B8%BB%E9%A2%98%E5%92%8C%E8%87%AA%E5%AE%9A%E4%B9%89%E5%9B%BE%E6%A0%87"><span class="toc-text">主题和自定义图标</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%99%BB%E5%BD%95%E9%A1%B5%E9%9D%A2%E4%B8%AD%E6%A0%87%E9%A2%98%E3%80%81%E8%83%8C%E6%99%AF%E5%9B%BE"><span class="toc-text">登录页面中标题、背景图</span></a></li></ol></li></ol></li></ol></div></div><div class="card-widget card-recent-post"><div class="item-headline"><a class="faa-parent animated-hover"><svg class="faa-tada icon" style="height:30px;width:25px;fill:currentColor;position:relative;top:5px" aria-hidden="true"><use href="#icon-zuixinshijuan"></use></svg></a><span>最新文章</span></div><div class="aside-list"><div class="aside-list-item"><a class="thumbnail" href="/2025/04/13/%E8%8B%A5%E4%BE%9D%E5%9F%BA%E7%A1%80%E5%BA%94%E7%94%A8%E7%AF%87/" title="若依框架"><img src= "" data-lazy-src="/img/bac-1.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="若依框架"/></a><div class="content"><a class="title" href="/2025/04/13/%E8%8B%A5%E4%BE%9D%E5%9F%BA%E7%A1%80%E5%BA%94%E7%94%A8%E7%AF%87/" title="若依框架">若依框架</a><time datetime="2025-04-12T16:00:00.000Z" title="发表于 2025-04-13 00:00:00">2025-04-13</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/2025/04/11/JUC/" title="JUC"><img src= "" data-lazy-src="/img/bac-4.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="JUC"/></a><div class="content"><a class="title" href="/2025/04/11/JUC/" title="JUC">JUC</a><time datetime="2025-04-10T16:00:00.000Z" title="发表于 2025-04-11 00:00:00">2025-04-11</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/2025/04/11/%E5%A4%9A%E7%BA%BF%E7%A8%8B/" title="多线程"><img src= "" data-lazy-src="/img/bac-7.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="多线程"/></a><div class="content"><a class="title" href="/2025/04/11/%E5%A4%9A%E7%BA%BF%E7%A8%8B/" title="多线程">多线程</a><time datetime="2025-04-10T16:00:00.000Z" title="发表于 2025-04-11 00:00:00">2025-04-11</time></div></div></div></div></div></div></main><footer id="footer"><div id="footer-wrap"><div id="ft"><div class="ft-item-1"><div class="t-top"><div class="t-t-l"><p class="ft-t t-l-t">格言🧬</p><div class="bg-ad"><div> 不必匆忙赶路，慢下来感受阳光与微风。生活不会永远完美，但总有不期而遇的温暖。累了就停一停，但别忘记，你走过的每一步都在铺垫未来的惊喜✨</div><div class="btn-xz-box"><a class="btn-xz" target="_blank" rel="noopener" href="https://raw.githubusercontent.com/SRS-Blog/SRS-Blog.github.io/main/img/bac-14.jpg">点击开启星辰之旅</a></div></div></div><div class="t-t-r"><p class="ft-t t-l-t">猜你想看💡</p><ul class="ft-links"><li><a target="_blank" rel="noopener" href="https://www.fomal.cc/posts/eec9786.html">魔改指南</a><a href="/comments/">留点什么</a></li><li><a href="/link/">我的朋友</a><a href="/Gallery/">我的照片</a></li><li><a href="/game/">我的游戏</a><a href="/music/">我的音乐</a></li><li><a href="/categories/">文章分类</a><a href="/tags/">文章标签</a></li><li><a href="/about/">关于作者</a><a target="_blank" rel="noopener" href="https://www.fomal.cc/posts/e593433d.html">网址导航</a></li></ul></div></div></div><div class="ft-item-2"><p class="ft-t">推荐友链⌛</p><div class="ft-img-group"><div class="img-group-item"><a href="/img/wechat.jpg" title="SRS🥝"><img src= "" data-lazy-src="/img/srs.jpg" alt=""/></a></div><div class="img-group-item"><a href="/img/xxwechat.jpg" title="潇潇🥝"><img src= "" data-lazy-src="/img/wyx.jpg" alt=""/></a></div></div></div></div><div class="copyright"><span><b>&copy;2025</b></span><span><b>&nbsp;&nbsp;By SRS</b></span></div><div id="workboard"><link rel="stylesheet" href="/css/runtime.css"/><script src="/js/runtime.js"></script></div><p id="ghbdages"><!-- SRS-Blog 徽标--><a class="github-badge" target="_blank" href="https://github.com/SRS-Blog" style="margin-inline:5px" title="SRS-Blog"><img src= "" data-lazy-src="https://img.shields.io/badge/SRS-Me-red" alt="SRS-Blog"/></a><!-- Hexo 徽标--><a class="github-badge" target="_blank" href="https://hexo.io/" style="margin-inline:5px" title="博客框架为Hexo"><img src= "" data-lazy-src="https://img.shields.io/badge/Frame-Hexo-blue?style=flat&amp;logo=hexo" alt="Hexo"/></a><!-- Butterfly 徽标--><a class="github-badge" target="_blank" href="https://butterfly.js.org/" style="margin-inline:5px" title="主题Butterfly"><img src= "" data-lazy-src="https://img.shields.io/badge/Theme-Butterfly-6513df?style=flat&amp;logo=bitdefender" alt="Butterfly"/></a><!-- Netlify 徽标--><a class="github-badge" target="_blank" href="https://app.netlify.com/" style="margin-inline:5px" title="Netlify部署"><img src= "" data-lazy-src="https://img.shields.io/badge/Deploy-Netlify-green" alt="Netlify"/></a><!-- Github 托管徽标--><a class="github-badge" target="_blank" href="https://github.com/" style="margin-inline:5px" title="本站项目由Github托管"><img src= "" data-lazy-src="https://img.shields.io/badge/Source-Github-d021d6?style=flat&amp;logo=GitHub" alt="Github"/></a><!-- CC 协议徽标--><a class="github-badge" target="_blank" href="http://creativecommons.org/licenses/by-nc-sa/4.0/" style="margin-inline:5px" title="本站采用知识共享署名-非商业性使用"><img src= "" data-lazy-src="https://img.shields.io/badge/Copyright-BY--NC--SA%204.0-d42328?style=flat&amp;logo=Claris" alt="CC BY-NC-SA 4.0"/></a></p></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="translateLink" type="button" title="简繁转换">繁</button><button id="darkmode" type="button" title="日间和夜间模式切换"><i class="fas fa-adjust"></i></button></div><div id="rightside-config-show"><button id="rightside-config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="share" type="button" title="分享链接" onclick="share()"><i class="fas fa-share-nodes"></i></button><a id="to_comment" href="#post-comment" title="前往评论"><i class="fas fa-comments"></i></a><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i><span id="percent">0<span>%</span></span></button><button id="go-down" type="button" title="直达底部" onclick="btf.scrollToDest(document.body.scrollHeight, 500)"><i class="fas fa-arrow-down"></i></button></div></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="/js/tw_cn.js"></script><script src="https://cdn.jsdelivr.net/npm/instant.page/instantpage.min.js" type="module"></script><script src="https://cdn.jsdelivr.net/npm/vanilla-lazyload/dist/lazyload.iife.min.js"></script><script src="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.js"></script><div class="js-pjax"><script>(() => {
  const isShuoshuo = GLOBAL_CONFIG_SITE.pageType === 'shuoshuo'
  const option = null

  const getCount = () => {
    const countELement = document.getElementById('twikoo-count')
    if(!countELement) return
    twikoo.getCommentsCount({
      envId: 'https://ubiquitous-panda-07c371.netlify.app/.netlify/functions/twikoo',
      region: '',
      urls: [window.location.pathname],
      includeReply: false
    }).then(res => {
      countELement.textContent = res[0].count
    }).catch(err => {
      console.error(err)
    })
  }

  const init = (el = document, path = location.pathname) => {
    twikoo.init({
      el: el.querySelector('#twikoo-wrap'),
      envId: 'https://ubiquitous-panda-07c371.netlify.app/.netlify/functions/twikoo',
      region: '',
      onCommentLoaded: () => {
        btf.loadLightbox(document.querySelectorAll('#twikoo .tk-content img:not(.tk-owo-emotion)'))
      },
      ...option,
      path: isShuoshuo ? path : (option && option.path) || path
    })

    

    isShuoshuo && (window.shuoshuoComment.destroyTwikoo = () => {
      if (el.children.length) {
        el.innerHTML = ''
        el.classList.add('no-comment')
      }
    })
  }

  const loadTwikoo = (el, path) => {
    if (typeof twikoo === 'object') setTimeout(() => init(el, path), 0)
    else btf.getScript('https://cdn.jsdelivr.net/npm/twikoo/dist/twikoo.all.min.js').then(() => init(el, path))
  }

  if (isShuoshuo) {
    'Twikoo' === 'Twikoo'
      ? window.shuoshuoComment = { loadComment: loadTwikoo }
      : window.loadOtherComment = loadTwikoo
    return
  }

  if ('Twikoo' === 'Twikoo' || !true) {
    if (true) btf.loadComment(document.getElementById('twikoo-wrap'), loadTwikoo)
    else loadTwikoo()
  } else {
    window.loadOtherComment = loadTwikoo
  }
})()</script></div><script async data-pjax src="/js/txmap.js"></script><script src="https://npm.elemecdn.com/jquery@latest/dist/jquery.min.js"></script><script defer src="/js/light.js"></script><canvas id="universe"></canvas><script defer src="/js/universe.js"></script><script defer src="/js/cursor.js"></script><script defer src="/js/emoji.js"></script><script async src="//npm.elemecdn.com/pace-js@1.2.4/pace.min.js"></script><div class="aplayer no-destroy" data-id="9472457949" data-server="tencent" data-type="playlist" data-fixed="true" data-autoplay="true"> </div><script async src="//at.alicdn.com/t/c/font_4887470_r6tyhzjqh8q.js"></script><script src="/js/nav.js"></script><script defer data-pjax src="/js/readPercent.js"></script><script async src="https://npm.elemecdn.com/tzy-blog/lib/js/other/sakura.js"></script><script async src="/js/title.js"></script><script async src="https://cdn1.tianli0.top/npm/vue@2.6.14/dist/vue.min.js"></script><script async src="https://cdn1.tianli0.top/npm/element-ui@2.15.6/lib/index.js"></script><script src="https://cdn.bootcdn.net/ajax/libs/clipboard.js/2.0.11/clipboard.min.js"></script><script src="/js/share.js"></script><script id="canvas_nest" defer="defer" color="0,0,255" opacity="0.7" zIndex="-1" count="30" mobile="false" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/dist/canvas-nest.min.js"></script><script id="click-heart" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/dist/click-heart.min.js" async="async" mobile="true"></script><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js"></script><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/metingjs/dist/Meting.min.js"></script><script>(() => {
  const destroyAplayer = () => {
    if (window.aplayers) {
      for (let i = 0; i < window.aplayers.length; i++) {
        if (!window.aplayers[i].options.fixed) {
          window.aplayers[i].destroy()
        }
      }
    }
  }

  const runMetingJS = () => {
    typeof loadMeting === 'function' && document.getElementsByClassName('aplayer').length && loadMeting()
  }

  btf.addGlobalFn('pjaxSend', destroyAplayer, 'destroyAplayer')
  btf.addGlobalFn('pjaxComplete', loadMeting, 'runMetingJS')
})()</script><script src="https://cdn.jsdelivr.net/npm/pjax/pjax.min.js"></script><script>(() => {
  const pjaxSelectors = ["head > title","#config-diff","#body-wrap","#rightside-config-hide","#rightside-config-show",".js-pjax"]

  window.pjax = new Pjax({
    elements: 'a:not([target="_blank"])',
    selectors: pjaxSelectors,
    cacheBust: false,
    analytics: false,
    scrollRestoration: false
  })

  const triggerPjaxFn = (val) => {
    if (!val) return
    Object.values(val).forEach(fn => fn())
  }

  document.addEventListener('pjax:send', () => {
    // removeEventListener
    btf.removeGlobalFnEvent('pjaxSendOnce')
    btf.removeGlobalFnEvent('themeChange')

    // reset readmode
    const $bodyClassList = document.body.classList
    if ($bodyClassList.contains('read-mode')) $bodyClassList.remove('read-mode')

    triggerPjaxFn(window.globalFn.pjaxSend)
  })

  document.addEventListener('pjax:complete', () => {
    btf.removeGlobalFnEvent('pjaxCompleteOnce')
    document.querySelectorAll('script[data-pjax]').forEach(item => {
      const newScript = document.createElement('script')
      const content = item.text || item.textContent || item.innerHTML || ""
      Array.from(item.attributes).forEach(attr => newScript.setAttribute(attr.name, attr.value))
      newScript.appendChild(document.createTextNode(content))
      item.parentNode.replaceChild(newScript, item)
    })

    triggerPjaxFn(window.globalFn.pjaxComplete)
  })

  document.addEventListener('pjax:error', e => {
    if (e.request.status === 404) {
      const usePjax = true
      true 
        ? (usePjax ? pjax.loadUrl('/404.html') : window.location.href = '/404.html')
        : window.location.href = e.request.responseURL
    }
  })
})()</script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script><div id="local-search"><div class="search-dialog"><nav class="search-nav"><span class="search-dialog-title">搜索</span><span id="loading-status"></span><button class="search-close-button"><i class="fas fa-times"></i></button></nav><div class="text-center" id="loading-database"><i class="fas fa-spinner fa-pulse"></i><span>  数据加载中</span></div><div class="search-wrap"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div><hr/><div id="local-search-results"></div><div id="local-search-stats-wrap"></div></div></div><div id="search-mask"></div><script src="/js/search/local-search.js"></script></div></div><!-- hexo injector body_end start --> <script data-pjax>if(document.getElementById('recent-posts') && (location.pathname ==='/'|| '/' ==='all')){
    var parent = document.getElementById('recent-posts');
    var child = '<div class="recent-post-item" style="width:100%;height: auto"><div id="catalog_magnet"><div class="magnet_item"><a class="magnet_link" href="https://srs-blog.github.io/categories/PYTHON/"><div class="magnet_link_context" style=""><span style="font-weight:500;flex:1">📚 PYTHON (1)</span><span style="padding:0px 4px;border-radius: 8px;"><i class="fas fa-arrow-circle-right"></i></span></div></a></div><div class="magnet_item"><a class="magnet_link" href="https://srs-blog.github.io/categories/C/"><div class="magnet_link_context" style=""><span style="font-weight:500;flex:1">🎮 C++ (1)</span><span style="padding:0px 4px;border-radius: 8px;"><i class="fas fa-arrow-circle-right"></i></span></div></a></div><div class="magnet_item"><a class="magnet_link" href="https://srs-blog.github.io/categories/Hexo/"><div class="magnet_link_context" style=""><span style="font-weight:500;flex:1">🐱‍👓 Hexo (1)</span><span style="padding:0px 4px;border-radius: 8px;"><i class="fas fa-arrow-circle-right"></i></span></div></a></div><div class="magnet_item"><a class="magnet_link" href="https://srs-blog.github.io/categories/Java/"><div class="magnet_link_context" style=""><span style="font-weight:500;flex:1">👩‍💻 Java (6)</span><span style="padding:0px 4px;border-radius: 8px;"><i class="fas fa-arrow-circle-right"></i></span></div></a></div><a class="magnet_link_more"  href="https://srs-blog.github.io/categories" style="flex:1;text-align: center;margin-bottom: 10px;">查看更多...</a></div></div>';
    console.log('已挂载magnet')
    parent.insertAdjacentHTML("afterbegin",child)}
     </script><style>#catalog_magnet{flex-wrap: wrap;display: flex;width:100%;justify-content:space-between;padding: 10px 10px 0 10px;align-content: flex-start;}.magnet_item{flex-basis: calc(50% - 5px);background: #f2f2f2;margin-bottom: 10px;border-radius: 8px;transition: all 0.2s ease-in-out;}.magnet_item:hover{background: #b30070}.magnet_link_more{color:#555}.magnet_link{color:black}.magnet_link:hover{color:white}@media screen and (max-width: 600px) {.magnet_item {flex-basis: 100%;}}.magnet_link_context{display:flex;padding: 10px;font-size:16px;transition: all 0.2s ease-in-out;}.magnet_link_context:hover{padding: 10px 20px;}</style>
    <style></style><script data-pjax>
  function butterfly_swiper_injector_config(){
    var parent_div_git = document.getElementById('recent-posts');
    var item_html = '<div class="recent-post-item" style="height: auto;width: 100%"><div class="blog-slider swiper-container-fade swiper-container-horizontal" id="swiper_container"><div class="blog-slider__wrp swiper-wrapper" style="transition-duration: 0ms;"><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" onclick="pjax.loadUrl(&quot;2025/04/08/2025-4-8-第一篇文章/&quot;);" href="javascript:void(0);" alt=""><img width="48" height="48" src= "" data-lazy-src="/img/bac-13.jpg" alt="" onerror="this.src=https://unpkg.zhimg.com/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2025-04-08</span><a class="blog-slider__title" onclick="pjax.loadUrl(&quot;2025/04/08/2025-4-8-第一篇文章/&quot;);" href="javascript:void(0);" alt="">第一篇文章</a><div class="blog-slider__text">再怎么看我也不知道怎么描述它的啦！</div><a class="blog-slider__button" onclick="pjax.loadUrl(&quot;2025/04/08/2025-4-8-第一篇文章/&quot;);" href="javascript:void(0);" alt="">详情       </a></div></div><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" onclick="pjax.loadUrl(&quot;2025/04/08/2025-4-8-第二篇文章/&quot;);" href="javascript:void(0);" alt=""><img width="48" height="48" src= "" data-lazy-src="/img/bac-9.jpg" alt="" onerror="this.src=https://unpkg.zhimg.com/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2025-04-08</span><a class="blog-slider__title" onclick="pjax.loadUrl(&quot;2025/04/08/2025-4-8-第二篇文章/&quot;);" href="javascript:void(0);" alt="">第二篇文章</a><div class="blog-slider__text">再怎么看我也不知道怎么描述它的啦！</div><a class="blog-slider__button" onclick="pjax.loadUrl(&quot;2025/04/08/2025-4-8-第二篇文章/&quot;);" href="javascript:void(0);" alt="">详情       </a></div></div><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" onclick="pjax.loadUrl(&quot;2025/04/08/2025-4-8-第三篇文章/&quot;);" href="javascript:void(0);" alt=""><img width="48" height="48" src= "" data-lazy-src="/img/bac-15.jpg" alt="" onerror="this.src=https://unpkg.zhimg.com/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2025-04-08</span><a class="blog-slider__title" onclick="pjax.loadUrl(&quot;2025/04/08/2025-4-8-第三篇文章/&quot;);" href="javascript:void(0);" alt="">第三篇文章</a><div class="blog-slider__text">再怎么看我也不知道怎么描述它的啦！</div><a class="blog-slider__button" onclick="pjax.loadUrl(&quot;2025/04/08/2025-4-8-第三篇文章/&quot;);" href="javascript:void(0);" alt="">详情       </a></div></div><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" onclick="pjax.loadUrl(&quot;2025/04/13/若依基础应用篇/&quot;);" href="javascript:void(0);" alt=""><img width="48" height="48" src= "" data-lazy-src="/img/bac-1.jpg" alt="" onerror="this.src=https://unpkg.zhimg.com/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2025-04-13</span><a class="blog-slider__title" onclick="pjax.loadUrl(&quot;2025/04/13/若依基础应用篇/&quot;);" href="javascript:void(0);" alt="">若依框架</a><div class="blog-slider__text">再怎么看我也不知道怎么描述它的啦！</div><a class="blog-slider__button" onclick="pjax.loadUrl(&quot;2025/04/13/若依基础应用篇/&quot;);" href="javascript:void(0);" alt="">详情       </a></div></div><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" onclick="pjax.loadUrl(&quot;2025/04/11/多线程/&quot;);" href="javascript:void(0);" alt=""><img width="48" height="48" src= "" data-lazy-src="/img/bac-7.jpg" alt="" onerror="this.src=https://unpkg.zhimg.com/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2025-04-11</span><a class="blog-slider__title" onclick="pjax.loadUrl(&quot;2025/04/11/多线程/&quot;);" href="javascript:void(0);" alt="">多线程</a><div class="blog-slider__text">再怎么看我也不知道怎么描述它的啦！</div><a class="blog-slider__button" onclick="pjax.loadUrl(&quot;2025/04/11/多线程/&quot;);" href="javascript:void(0);" alt="">详情       </a></div></div><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" onclick="pjax.loadUrl(&quot;2025/04/11/JUC/&quot;);" href="javascript:void(0);" alt=""><img width="48" height="48" src= "" data-lazy-src="/img/bac-4.jpg" alt="" onerror="this.src=https://unpkg.zhimg.com/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2025-04-11</span><a class="blog-slider__title" onclick="pjax.loadUrl(&quot;2025/04/11/JUC/&quot;);" href="javascript:void(0);" alt="">JUC</a><div class="blog-slider__text">再怎么看我也不知道怎么描述它的啦！</div><a class="blog-slider__button" onclick="pjax.loadUrl(&quot;2025/04/11/JUC/&quot;);" href="javascript:void(0);" alt="">详情       </a></div></div><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" onclick="pjax.loadUrl(&quot;2025/04/10/IO-异常-File-综合案例/&quot;);" href="javascript:void(0);" alt=""><img width="48" height="48" src= "" data-lazy-src="/img/bac-12.jpg" alt="" onerror="this.src=https://unpkg.zhimg.com/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2025-04-10</span><a class="blog-slider__title" onclick="pjax.loadUrl(&quot;2025/04/10/IO-异常-File-综合案例/&quot;);" href="javascript:void(0);" alt="">异常&amp;File</a><div class="blog-slider__text">再怎么看我也不知道怎么描述它的啦！</div><a class="blog-slider__button" onclick="pjax.loadUrl(&quot;2025/04/10/IO-异常-File-综合案例/&quot;);" href="javascript:void(0);" alt="">详情       </a></div></div><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" onclick="pjax.loadUrl(&quot;2025/04/10/IO流-字节流-字符流/&quot;);" href="javascript:void(0);" alt=""><img width="48" height="48" src= "" data-lazy-src="/img/bac-15.jpg" alt="" onerror="this.src=https://unpkg.zhimg.com/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2025-04-10</span><a class="blog-slider__title" onclick="pjax.loadUrl(&quot;2025/04/10/IO流-字节流-字符流/&quot;);" href="javascript:void(0);" alt="">IO流</a><div class="blog-slider__text">再怎么看我也不知道怎么描述它的啦！</div><a class="blog-slider__button" onclick="pjax.loadUrl(&quot;2025/04/10/IO流-字节流-字符流/&quot;);" href="javascript:void(0);" alt="">详情       </a></div></div><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" onclick="pjax.loadUrl(&quot;2025/04/10/IO流-其他流/&quot;);" href="javascript:void(0);" alt=""><img width="48" height="48" src= "" data-lazy-src="/img/bac-13.jpg" alt="" onerror="this.src=https://unpkg.zhimg.com/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2025-04-10</span><a class="blog-slider__title" onclick="pjax.loadUrl(&quot;2025/04/10/IO流-其他流/&quot;);" href="javascript:void(0);" alt="">IO流--扩展流</a><div class="blog-slider__text">再怎么看我也不知道怎么描述它的啦！</div><a class="blog-slider__button" onclick="pjax.loadUrl(&quot;2025/04/10/IO流-其他流/&quot;);" href="javascript:void(0);" alt="">详情       </a></div></div></div><div class="blog-slider__pagination swiper-pagination-clickable swiper-pagination-bullets"></div></div></div>';
    console.log('已挂载butterfly_swiper')
    parent_div_git.insertAdjacentHTML("afterbegin",item_html)
    }
  var elist = 'undefined'.split(',');
  var cpage = location.pathname;
  var epage = '/';
  var flag = 0;

  for (var i=0;i<elist.length;i++){
    if (cpage.includes(elist[i])){
      flag++;
    }
  }

  if ((epage ==='all')&&(flag == 0)){
    butterfly_swiper_injector_config();
  }
  else if (epage === cpage){
    butterfly_swiper_injector_config();
  }
  </script><script defer src="https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiper.min.js"></script><script defer data-pjax src="https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiper_init.js"></script><div class="js-pjax"><script async="async">var arr = document.getElementsByClassName('recent-post-item');
for(var i = 0;i<arr.length;i++){
    arr[i].classList.add('wow');
    arr[i].classList.add('animate__zoomIn');
    arr[i].setAttribute('data-wow-duration', '2s');
    arr[i].setAttribute('data-wow-delay', '1s');
    arr[i].setAttribute('data-wow-offset', '100');
    arr[i].setAttribute('data-wow-iteration', '2');
  }</script><script async="async">var arr = document.getElementsByClassName('card-widget');
for(var i = 0;i<arr.length;i++){
    arr[i].classList.add('wow');
    arr[i].classList.add('animate__zoomIn');
    arr[i].setAttribute('data-wow-duration', '');
    arr[i].setAttribute('data-wow-delay', '');
    arr[i].setAttribute('data-wow-offset', '');
    arr[i].setAttribute('data-wow-iteration', '');
  }</script></div><script defer src="https://npm.elemecdn.com/hexo-butterfly-wowjs/lib/wow.min.js"></script><script defer src="https://npm.elemecdn.com/hexo-butterfly-wowjs/lib/wow_init.js"></script><script async src="//at.alicdn.com/t/font_2032782_8d5kxvn09md.js"></script><!-- hexo injector body_end end --><script src="/live2dw/lib/L2Dwidget.min.js?094cbace49a39548bed64abff5988b05"></script><script>L2Dwidget.init({"pluginRootPath":"live2dw/","pluginJsPath":"lib/","pluginModelPath":"assets/","tagMode":false,"debug":false,"model":{"jsonPath":"/live2dw/assets/haruto.model.json"},"display":{"position":"right","width":160,"height":260},"mobile":{"show":true},"log":false});</script></body></html>